Railsでユーザの権限を管理するには、下にある3つのgemを組み合わせて使う方法があります。
実装方法は「Devise CanCanCan rolify Tutorial」に説明がありますが、知らないことが多くてハマったのでメモしておきます。
インストール
Gemfileに下の3つを追加して、bundle install
を実行します。
gem 'devise'
gem 'cancancan'
gem 'rolify'
以下のコマンドを実行し、権限管理の機能を備えたUserモデルを生成します。
$ rails generate devise:install
$ rails generate devise User
$ rails generate cancan:ability
$ rails generate rolify Role User
$ rake db:migrate
自分の場合は、既にUserモデルが存在していて、自前のログイン認証ロジックを組み込んでいたのですが、rails d model user
で破棄してから実行しました。
Deviseの設定
config/routes.rb
にrootの設定をします。
root to: "home#index" # ログイン後に遷移させるアクションを指定
認証が必要なコントローラにbefore_action :authenticate_user!
を記述します。
class HomeController < ApplicationController
before_action :authenticate_user!
def index
end
end
また、DeviseのメーラーにデフォルトURLを設定します。意味は分かりません。
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
これにより、コントローラやビューで、user_signed_in?
やcurrent_user
などのヘルパーを使うことができます。詳細は「Devise README」を参照。
ログインページのカスタマイズ
ログインページのデザインを変更するには、次のコマンドを実行してapp/views/devise
の下にビューを生成します。
$ rails generate devise:views
# 作成されたビュー
$ ls app/views/devise/
confirmations mailer passwords registrations sessions shared unlocks
# ログインページはこれを編集する
$ vim app/views/devise/sessions/new.html.erb
日本語化
Deviseのローカライズファイルをダウンロードしてconfig/locales/
の下に配置します。
$ wget https://gist.githubusercontent.com/satour/6c15f27211fdc0de58b4/raw/d4b5815295c65021790569c9be447d15760f4957/devise.ja.yml -P config/locales/
権限の設定
CanCanCanが生成した、app/models/ability.rb
に権限を定義します。
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
# 基本ルール
if user.has_role? :admin
can :manage, :all # adminロールは何でもできる
else
can :read, :all # それ以外は参照のみ
end
end
end
-
user.has_role?
の引数には任意のシンボルが使えます -
can
の第1引数には、:manage
、:create
、:read
、:update
、:destroy
といったパーミッションを指定します -
can
の第2引数には、対象となるオブジェクトのクラス名を指定します
詳しい説明は「CanCanCommunity wiki - Defining Abilities」にあります。
ユーザにロールを割り当てる
例) rails console
で新規にユーザを作成して、adminロールを割り当てる
$ rails c
# ユーザ"hoge"を作成する
> user = User.new
> user.email = "hoge@example.com"
> user.password = "test1234"
> user.save
# ユーザ"hoge"に"admin"ロールを設定する
> user.add_role "admin"
ユーザには複数のロールを割り当てることができます。
ビューでの判定
ユーザのロールで表示を切り替えるには、
<% if user.has_role? :admin %>
...ここにadminユーザだけに表示されるコンテンツ...
<% end %>
以上