Building a Blog with Ruby on Rails 7, Hotwire, and Turbo - Part 4: Authentication and Admin Interface with Devise

Coding Posted on May 17, 2023
Welcome back to our series on building a blog with Ruby on Rails 7, Hotwire, and Turbo! In this post, we'll focus on adding authentication using the Devise gem and creating an admin interface to manage our blog posts, categories, and tags.

Step 1: Installing Devise


First, add the Devise gem to your Gemfile and run bundle install:

gem 'devise'

Next, run the Devise generator:

rails generate devise:install 

Follow the instructions output by the generator to complete the setup.

Step 2: Creating a User Model


Now, let's create a User model for authentication:

rails generate devise User
rails db:migrate

Step 3: Adding Admin Role


Add an admin role to the User model. Update app/models/user.rb:

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  enum role: { user: 0, admin: 1 }
end

Step 4: Restricting Access to Admin Interface


Create a new controller called AdminController:

rails generate controller Admin 

Update the AdminController to inherit from ApplicationController and add a before_action to restrict access:

class AdminController < ApplicationController
  before_action :authenticate_user!
  before_action :require_admin

  private

  def require_admin
    unless current_user.admin?
      flash[:alert] = "You do not have permission to access this page."
      redirect_to root_path
    end
  end
end

Step 5: Creating Admin Interface for Managing Blog Posts, Categories, and Tags


Now, let's create admin views and controllers for managing blog posts, categories, and tags. Update the existing controllers to inherit from AdminController:

class PostsController < AdminController
  # ...
end

class CategoriesController < AdminController
  # ...
end

class TagsController < AdminController
  # ...
end

Create a new layout for the admin interface in app/views/layouts/admin.html.erb:

<!DOCTYPE html>
<html>
<head>
  <title>Admin - My Blog</title>
  <%= csrf_meta_tags %>
  <%= csp_meta_tag %>

  <%= stylesheet_link_tag 'application', media: 'all', 'data-turbo-track': 'reload' %>
  <%= javascript_pack_tag 'application', 'data-turbo-track': 'reload' %>
</head>

<body>
  <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
    <div class="container">
      <%= link_to "Admin", admin_path, class: "navbar-brand" %>
      <!-- Add navigation items here -->
    </div>
  </nav>

  <div class="container">
    <%= yield %>
  </div>
</body>
</html>

Update the admin views to use the new layout by adding the following line at the top of each view:

<% content_for :layout, "admin" %> 

Finally, update your routes in config/routes.rb to namespace the admin controllers:

Rails.application.routes.draw do
  devise_for :users
  namespace :admin do
    resources :posts
    resources :categories
    resources :tags
  end

  root to: 'posts#index'
end

Now, create a view for the admin dashboard in `app/views/admin/dashboard.html.erb`:

<% content_for :layout, "admin" %>

<h1>Admin Dashboard</h1>

<div class="row">
  <div class="col-md-4">
    <h3>Posts</h3>
    <%= link_to "View all posts", admin_posts_path, class: "btn btn-primary" %>
  </div>

  <div class="col-md-4">
    <h3>Categories</h3>
    <%= link_to "View all categories", admin_categories_path, class: "btn btn-primary" %>
  </div>

  <div class="col-md-4">
    <h3>Tags</h3>
    <%= link_to "View all tags", admin_tags_path, class: "btn btn-primary" %>
  </div>
</div>

Add a route for the admin dashboard in config/routes.rb:

Rails.application.routes.draw do
  devise_for :users

  namespace :admin do
    get '/', to: 'admin#dashboard'
    resources :posts
    resources :categories
    resources :tags
  end

  root to: 'posts#index'
end

With this admin interface, you can manage your blog posts, categories, and tags while ensuring that only admin users have access.

That concludes our series on building a blog with Ruby on Rails 7, Hotwire, and Turbo. We've covered creating the blog's foundation, integrating Bootstrap and a rich text editor, adding comments and SEO best practices, implementing analytics, discussing deployment options, and adding authentication and an admin interface. Now you have a fully-featured, secure, and easily manageable blog. Happy blogging!

Leave a comment:

Comments (0)