Railsでログイン機能を実装するときに便利なGemがdeviseです。
今回はそのdeviseの導入とview, そしてcontrollerのカスタマイズまでを記事にします。
###大まかな流れ
###1.deviseのインストール
gem 'devise'
$ rails g devise:install
###2.モデルの作成とマイグレーションファイルの実行
$ rails g devise User
$ rake db:migrate
###3.viewのカスタマイズ
$ rails g devise:views User
###4.controllerのカスタマイズ
$ rails g devise:controllers users
###5.sign_in,out後のルーティングの変更
##deviseのインストール
gem 'devise'
Gemfileに記入したらbundle installしましょう。
$ rails g devise:install
deviseをインストールします。
Running via Spring preloader in process 79831
create config/initializers/devise.rb
create config/locales/devise.en.yml
===============================================================================
Some setup you must do manually if you haven't yet:
1. Ensure you have defined default url options in your environments files. Here
is an example of default_url_options appropriate for a development environment
in config/environments/development.rb:
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
In production, :host should be set to the actual host of your application.
2. Ensure you have defined root_url to *something* in your config/routes.rb.
For example:
root to: "home#index"
3. Ensure you have flash messages in app/views/layouts/application.html.erb.
For example:
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
4. You can copy Devise views (for customization) to your app by running:
rails g devise:views
===============================================================================
1はログイン後にメールを送るときなどに設定します。
2は「config/routes.rbファイルにrootパスを定義していることを確認してください」という事が記述されています。
3はフラッシュメッセージを設定する際の説明です。ログイン/ログアウト後に"ログインしました"などの様なメッセージを表示させたい人は設定してみてください。
4はviewをカスタマイズしたい場合は'rails g devise:view'コマンドを打つ様に言っています。(※これに関しては少し詳しく説明していきます。)
##モデルを作成
###Userモデルを作っていきます
モデルの名前は任意なのでcustomerとかでも大丈夫です。
$ rails g devise User
作られるファイル一覧
migrationファイルが作成されるので追加したいカラムがある場合は追加してください。
後でカラムを追加する事も可能です。
def change
create_table :users do |t|
## Database authenticatable
t.string :name #追加したカラム
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
end
初期ではemailとパスワードのカラムがセットされています。
migrationファイルを実行
$ rake db:migrate
##テストユーザーを一括で登録したい場合
seedsファイルにデータを聞き込んであげましょう。
users = ["yamada", "abe", "tanaka", "yave", "kitani"]
users.each_with_index do |user, i|
User.create(
name: "#{user}",
email: "#{i + 1}@gamil.com",
password: "password"
)
end
# User.create(name: 'xxx', email: "a@gmail.co", password: "password")などでも大丈夫です。
$ rake db:seed
コマンドでテストデータが保存されます。
##追加したカラムを保存する
追加したカラムを保存したい場合は以下をapplicationControllerに記述しましょう。
sign_upだけでなくupdateも対応しているので自信で調べてみてください。(やり方はsign_upと同じですが)
class ApplicationController < ActionController::Base
before_action ::configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
end
end
deviseのstrongParameterに関して(英語)
##viewsのカスタマイズ
viewをカスタマイズさせるためのコマンド。
$ rails g devise:views User
Userのログイン周りのviewが作成されていきます。
views/users/~ | どこか |
---|---|
registrations/new | 新規登録画面 |
registrations/edit | プロフィールなど編集画面 |
sessions /new | ログイン画面 |
passwords/new | メール送信画面(パスワード変更用) |
passwords/edit | パスワード変更画面 |
confirmations/new | メールによる認証を行う画面 |
unlocks/new | アカウントのアンロック画面 |
viewが変更されない場合は下記を記述してみてください。
config.scoped_views = true
##deviseに対応したControllerのカスタマイズ
$ rails g devise:controllers users
これでdeviseのUsersControllerをインストールできます。
作られたコントローラーが使えるようroutes.rbを編集していきます。
devise_for :users, controllers: {
registrations: 'users/registrations',
sessions : 'users/sessions'
}
##sign_in, sign_out後のpath指定
ログイン/ログアウト後にpathを変更したい事があると思います。
デフォルトだとログイン後はrootパスに飛びます。
class ApplicationController < ActionController::Base
~~
private
def after_sign_in_path_for(resource)
mypage_root_path # ログイン後に遷移するpathを設定
end
def after_sign_out_path_for(resource)
new_user_session_path # ログアウト後に遷移するpathを設定
end
#飛ばしたいpathはrake routesコマンドを打ちperfixを確認してください!
管理画面などを作っていてdeviseのモデルが一つだけでなく2つ以上ある場合はadmin画面でsign_inした時も上に記述したpathにリダイレクトされることになるのでオーバーライドする必要があります。
この様な書き方も出来るだけで他にも方法はあるので自分の用途に合わせて調べてみてください。
参考にした記事(英語)
def after_sign_in_path_for(resource)
case resource
when Organizer
admin_events_path
end
end
def after_sign_out_path_for(resource_or_scope)
if resource_or_scope == :customer
root_path
elsif resource_or_scope == :organizer
new_organizer_session_path
end
end
カスタマイズをするとなると公式ドキュメントを読んだりと少し手間が発生しますがログイン/ログアウト機能をすぐに実装できる点は魅力だと思います。
devise以外の選択肢としてはauthlogic, sorceryなどがあるみたいです
ご覧いただきありがとうございました!