Rails4 + devise + cancancan + rails_adminが最強すぎ

Rails4 + devise + cancancan + rails_adminが最強過ぎたので自分用にメモ。

deviseで認証をして
cancancanでロール毎のパーミッションを割り当てて
rails_adminをdeviseとcancancanでadminユーザのみに使わせる

また、自分はrvmを使っているのでその辺りの設定も入っているが、使っていない場合はその辺りを無視で。

環境

  • Ruby 2.1.2
  • Rails 4.1.4
  • gem
    • devise 3.2.4
    • cancancan 1.8.4
    • rails_admin 0.6.2

今回のプロジェクト(sample)用にrvmの設定

rvmのgemsetを作成してrailsをインストール

rvm gemset create sample
rvm 2.1@sample
gem install rails

プロジェクト作成

railsプロジェクトの作成

rails new sample
cd sample/
rvm --rvmrc --create 2.1@sample

Gemfile

Gemfileを編集

gem 'devise'
gem 'cancancan'
gem 'rails_admin'

を追加

bundle installする

bundle install

deviseの設定

devise関連のファイルをgenerate

rails g devise:install

config/environments/development.rbを編集

config.action_mailer.default_url_options = { :host => 'localhost:3000' }

を追加

app/views/layouts/application.html.erbを編集

<% if notice %>
  <p class="alert alert-notice"><%= notice %></p>
<% end %>
<% if alert %>
  <p class="alert alert-error"><%= alert %></p>
<% end %>

を<%= yield %>の前あたりに追加。

deviceのユーザ管理モデルとロール、それらを結ぶ連結モデルの追加

rails g devise user
rails g model role name
rails g migration CreateJoinTableUserRole user role
rake db:migrate

app/models/user.rbを編集

  has_and_belongs_to_many :roles

  def has_role?(name)
    self.roles.where(name: name).length > 0
  end

app/models/role.rbを編集

  has_and_belongs_to_many :users

を追加。

cancancanの設定

cancancan関連のファイルをgenerate

rails g cancan:ability

app/models/ability.rbを編集

    if user.has_role?('admin')
      can :read, :all
      can :access, :rails_admin
      can :dashboard
      if user.has_role?('superadmin')
        can :manage, :all
      else
        can :manage, [] # A
      end
    else
      can :read, [] # B
      can :create, [] # C
    end

を追加。

  • superadminは全てのモデルの管理が可能
  • adminユーザは全てのモデルのreadと、Aで指定されたも出るの管理が可能
  • それ以外のユーザはBで指定されたモデルのreadと、Cで指定されたモデルのcreateが可能

アプリケーションの用途等に合わせて上記を変更する

rails_adminの設定

rails_admin関連のファイルをgenerate

rails g rails_admin:install
rake db:migrate

初期データ(管理者ユーザ)の作成

railsサーバの起動

rails s

http://localhost:3000/adminにアクセスして
Roleで

  • admin
  • superadmin

を作成して

Userでadminとsuperadminを関連付けた管理者ユーザを作成する。

終わったらCtrl+cでサーバを終了しておく。
スクリーンショットではログインしている状態だけどこの時点ではまだなので気にしない。

rails_adminの認証設定

config/initializers/rails_admin.rbを編集

  # config.authenticate_with do
  #   warden.authenticate! scope: :user
  # end
  # config.current_user_method(&:current_user)

  # config.authorize_with :cancan

となっているコメントを外す。

動作確認

railsサーバの起動

rails s

して

  • 先ほど作った管理者ユーザでログイン出来る
  • 全てのオブジェクトの管理が出来る
  • 管理者以外のユーザを作成して狙い通りに動く事

を確認する

おまけ

メール送信関連の設定
config/environments/development.rbを編集

  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    :address => 'smtp.gmail.com',
    :port => 587,
    :authentication => :plain,
    :user_name => 'メールアドレス',
    :password => 'パスワード'
  }

ログアウトをGETに変更
config/initializers/rails_admin.rbを編集
デフォルトではdeleteになっているので

  config.sign_out_via = :delete

getに変更しておくといいかも?

  config.sign_out_via = :get

ユーザSign up時にメール確認
db/migrate/*_devise_create_users.rbを編集

      ## Confirmable
      # t.string   :confirmation_token
      # t.datetime :confirmed_at
      # t.datetime :confirmation_sent_at
      # t.string   :unconfirmed_email # Only if using reconfirmable

コメントアウトを外す。
app/models/user.rbを編集

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :confirmable

:confirmableを追加