Want a simple login for your rails app? I'll cover that in this tutorial.
We will require the user to login in order to gain access to certain pages. Take note that this is a simple login, user roles and authentication won't be covered in this post.
First, we will create simple pages to demonstrate the website requiring the user to log in.
Create Pages
I'll create two pages, admin and home.
Create the views, admin.html.erb
and home.html.erb
at app/views/pages/
.
// app/views/pages/admin.html.erb
<h1>Admin Home</h1>
<p>app/views/pages/admin.html.erb</p>
// app/views/pages/home.html.erb
<h1>Home</h1>
<p>app/views/pages/home.html.erb</p>
Now create the controller for these pages at app/controllers/
.
# app/controllers/pages_controller.rb
class PagesController < ApplicationController
def home
end
def admin
end
end
Finally, create routes for these pages.
# config/routes.rb
get "/admin" => "pages#admin", as: "admin"
root "pages#home"
The pages should work by checking your localhost. The page for localhost:3000
should be app/views/pages/home.html.erb
and localhost:3000/admin
is app/views/pages/admin.html.erb
.
Create Login
Now the pages were done, we will start implementing a login system. I'll be using devise gem. It has all of the things we need for a simple login.
-
Install devise gem by adding this to your Gemfile:
gem 'devise'
Then run bundle install.
-
Generate necessary files for devise running this in your terminal:
$ rails generate devise:install
If you're using rails 7 you may encounter an error. You may need to paste this code in your
config/initializers/devise.rb
:
config.navigational_formats = ['*/*', :html, :turbo_stream]
source -
Create the migration files we would be using.
$ rails generate devise MODEL
Replace
MODEL
with the class name used for the applicationโs users (I mostly useUser
but could also beAdmin
).Then run
rails db:migrate
. -
Require the user to log in when visiting the admin page.
You could do this by updating
app/controllers/pages
.
class PagesController < ApplicationController before_action :authenticate_user!, only: :admin def home end def admin end end
The
before_action :authenticate_user!
will check if the user is logged in. Depending on the model you might need to change toauthenticate_MODEL!
, example, if you chose to name your devise modelAdmin
then it should beauthenticate_admin!
.By adding
only: :admin
the action is only performed at admin action(app/views/pages/admin.html.erb).
That should do it! Restart your server and check it out!
Add links (Optional)
In here, I'll add a sign in and sign out links for the website.
-
Create file
_user_detail.html.erb
atapp/views/shared/
.
// app/views/shared/_user_detail.html.erb <% if user_signed_in? %> <%= button_to("Log Out", destroy_user_session_path, method: :delete) %> <% else %> <%= link_to 'Log in', new_user_session_path %> <% end %>
If you're using rails 7 logout button may not work properly you need to use this:
<%= button_to("Log Out", LOGOUT_PATH, method: :delete) %>
sourceThe paths here are the login in and sign out. You could check yours by running
rails routes
.The
user_signed_in?
is a helper in devise. It returns true or false depending on if the user is logged in. This might changed depending on the chosen name for the devise model. If you choseAdmin
then it should beadmin_signed_in?
. -
Add links to
app/views/pages/home.html.erb
andapp/views/pages/admin.html.erb
.
<%= render "shared/user_detail"%>
References:
- https://stackoverflow.com/questions/36646226/undefined-method-user-url-for-devise-sessionscontrollercreate
- https://dev.to/spaquet/rails-7-devise-log-out-d1n
- https://github.com/heartcombo/devise
You could check out my repository here.
Please do not repost
Top comments (0)