[RUBY] [Note] How to use Rails 6 Devise + cancancan

Introduction

After creating a User model (authentication) using devise Added cancancan to allow authorization.

Log the process as a memorandum.

Add the devise gem.

・
・
・
gem 'devise'

Install the bundle.

$bundle install

Install the device.

$rails generate devise:install

Check if there is a setting.

config/environments/development.rb


・
・
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

Add page # index.

config/routes.rb


Rails.application.routes.draw do
root to: "page#index"
・
・
end

Add the following.

app/views/layouts/application.html.erb



<body>
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
・
・
</body>

Install View.

$ rails g devise:views

The following is created.

app/views/devise/unlocks/new.html.erb app/views/devise/shared/_links.html.erb app/views/devise/shared/_error_messages.html.erb app/views/devise/sessions/new.html.erb app/views/devise/registrations/new.html.erb app/views/devise/registrations/edit.html.erb app/views/devise/passwords/new.html.erb app/views/devise/passwords/edit.html.erb app/views/devise/mailer/unlock_instructions.html.erb app/views/devise/mailer/reset_password_instructions.html.erb app/views/devise/mailer/password_change.html.erb app/views/devise/mailer/email_changed.html.erb app/views/devise/mailer/confirmation_instructions.html.erb app/views/devise/confirmations/new.html.erb

Create a model. This time we will create a User model.

$ rails g devise user

The following model is created.

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
end

The following are created at the same time.

config/application.rb


config.i18n.default_locale = :ja

The following is also made.

config/routes.rb


ails.application.routes.draw do
devise_for :users
・
・
end

After creating the model, it will be reflected in the DB.

rails db:migrate

Since there is no View of page # index yet, I will create it.

$ rails g controller Pages index

As an aside, you can change the Path by creating a scope in routes.rb.

routes.rb


  devise_scope :user do
    get 'login', to: 'devise/sessions#new'
    post 'login', to: 'devise/sessions/#create'
    delete 'logout', to: 'devise/sessions#destroy' 
  end

This will http://localhost:3000/login The login page is displayed when you access.

Of course, the login page is displayed even with the default / users / sign_in, so delete it if necessary.

routes.rb


 devise_for :users, skip: [:sessions]

The device settings are complete.

cancancan installation

Next, install cancancan. This is called authorization, depending on the user It means granting access rights. This is the difference between a system administrator and a general user.

gem 'cancancan'

Install the bundle.

$bundle install

The Ability class is created.

rails g cancan:ability

This is the default for the Ability class.

class Ability
  include CanCan::Ability

  def initialize(user)
    # Define abilities for the passed in user here. For example:
    #
    #   user ||= User.new # guest user (not logged in)
    #   if user.admin?
    #     can :manage, :all
    #   else
    #     can :read, :all
    #   end
    #
    # The first argument to `can` is the action you are giving the user
    # permission to do.
    # If you pass :manage it will apply to every action. Other common actions
    # here are :read, :create, :update and :destroy.
    #
    # The second argument is the resource the user can perform the action on.
    # If you pass :all it will apply to every resource. Otherwise pass a Ruby
    # class of the resource.
    #
    # The third argument is an optional hash of conditions to further filter the
    # objects.
    # For example, here the user can only update published articles.
    #
    #   can :update, Article, :published => true
    #
    # See the wiki for details:
    # https://github.com/CanCanCommunity/cancancan/wiki/Defining-Abilities
  end
end

Change to:

# frozen_string_literal: true

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new
    can :read,  :all

    if user.admin? 
      can :manage,  :all

    end



    # Define abilities for the passed in user here. For example:
    #
    #   user ||= User.new # guest user (not logged in)
    #   if user.admin?
    #     can :manage, :all
    #   else
    #     can :read, :all
    #   end
    #
    # The first argument to `can` is the action you are giving the user
    # permission to do.
    # If you pass :manage it will apply to every action. Other common actions
    # here are :read, :create, :update and :destroy.
    #
    # The second argument is the resource the user can perform the action on.
    # If you pass :all it will apply to every resource. Otherwise pass a Ruby
    # class of the resource.
    #
    # The third argument is an optional hash of conditions to further filter the
    # objects.
    # For example, here the user can only update published articles.
    #
    #   can :update, Article, :published => true
    #
    # See the wiki for details:
    # https://github.com/CanCanCommunity/cancancan/wiki/Defining-Abilities
  end
end

user ||= User.new Without the above, an error occurred while operating as a guest user.

if user.admin? ← What is admin? I was asked.

def initialize(user) user ||= User.new can :read, :all When the Ability model is called If you are logged in as the initial value, the user is put in the variable, and if you are not logged in, the guest user is assigned to the variable. Then, it means that read authority is given to the user variable. This means that all users have read permission.

Please note that read permission is not tied to CRUD. It means that the page can be read, it does not mean that you can get it, and you can do it by programming the create method separately.

if user.admin? 
  can :manage,  :all

This is a program to be executed if true is entered in the admin column created in the User model. In other words, it is a user with administrator privileges.

Add the following to the View Page of Page # index.

app/views/pages/index.html.erb


<h1>Pages#index</h1>
<p>Find me in app/views/pages/index.html.erb</p>
  <%= link_to "Delete", logout_path, method: :delete %>

<% if can?  :update, current_user %>
  <h1>update</h1>

<% end %>

<% if can? :read, current_user %>
  <h1>read</h1>
<% end %>

<% if can? :update, current_user %> If the currently logged-in user has update permission, the contents will be displayed.

<% if can? :read, current_user %> If the logged-in user has read permission, the contents will be displayed.

It means that · · ·

db/schema.rb


  create_table "users", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.boolean "admin", default: false
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  end

In the above, admin is not in the User model, what should I do? I think it will be It will be added.

$rails g migration AddAdminToUser admin:boolean

The following is created by default default: Add "false".

On the view page, do not create a view that selects admin, but by default create a user with admin = false. Here, admin is intentionally created on the management side.

db/migrate/20200522114428_add_admin_to_users.rb



class AddAdminToUsers < ActiveRecord::Migration[6.0]
  def change
    add_column :users, :admin, :boolean, default: "false"
  end
end

Migrate

$rails g migrate

Check the DB schema.

db/schema.rb


 create_table "users", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.boolean "admin", default: false
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  end

http://localhost:3000/ Create a general user with.

admin user Create as follows.

$user =User.new(id: xx, email: "xxx@yyy", password: "xxxx", admin: true)

This completes the procedure, Actually for general users and Admin users respectively Go to Page # index.

Since general users have only read authority, read can be displayed.

Since the Admin user has manage authority (has all authority), read and update can be displayed respectively.

Recommended Posts

[Note] How to use Rails 6 Devise + cancancan
[Rails] How to use devise (Note)
[Rails] How to use gem "devise"
[Rails] How to use enum
[Rails] How to install devise
[Rails] How to use enum
How to use rails join
[Rails] How to use validation
[Rails] How to use authenticate_user!
[Rails] How to use "kaminari"
[Rails] How to use Scope
[rails] How to use devise helper method before_action: authenticate_user!
[Rails] How to use flash messages
How to use Ruby on Rails
[Introduction to Rails] How to use render
[Ruby on Rails] How to use CarrierWave
[Rails] How to use rails console with docker
How to use MySQL in Rails tutorial
How to use Java Scanner class (Note)
[Ruby on Rails] How to use redirect_to
[Ruby on Rails] How to use kaminari
[Rails] How to use video_tag to display videos
Ruby: CSV :: How to use Table Note
[Rails] How to use helper method, confimartion
How to use credentials.yml.enc introduced in Rails 5.2
[Rails] How to translate devise into Japanese
How to use Map
How to write Rails
How to use rbenv
How to use letter_opener_web
How to use fields_for
How to use java.util.logging
How to use map
How to use collection_select
How to use Twitter4J
How to use active_hash! !!
How to use MapStruct
How to use hidden_field_tag
How to use TreeSet
How to uninstall Rails
[How to use label]
How to use identity
How to use hashes
How to use JUnit 5
How to use Dozer.mapper
How to use Gradle
How to use org.immutables
How to use java.util.stream.Collector
How to use VisualVM
How to use Map
[Rails] How to use select boxes in Ransack
How to use rails g scaffold, functions, precautions
Note how to use Swift super basic TableView
How to use Segmented Control and points to note
How to use JQuery in js.erb of Rails6
[Rails] How to use Gem'rails-i18n' for Japanese support
[Ruby on Rails] How to use session method
[Rails] How to use PostgreSQL in Vagrant environment
[Java] How to use Map
[rails] How to post images
How to use Chain API