Rails deviseの導入とView + Controllerのカスタマイズ(sign_in/out後のpath指定など)

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**しましょう。

[![Image from Gyazo](https://i.gyazo.com/1628dd66c41428eb7428d9dec2b201ff.png)](https://gyazo.com/1628dd66c41428eb7428d9dec2b201ff)
無事インストールされていたら進めていきましょう。

```
$ 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

===============================================================================
```

１はログイン後にメールを送るときなどに設定します。

２は「config/routes.rbファイルにrootパスを定義していることを確認してください」という事が記述されています。

３はフラッシュメッセージを設定する際の説明です。ログイン/ログアウト後に"ログインしました"などの様なメッセージを表示させたい人は設定してみてください。

４はviewをカスタマイズしたい場合は'rails g devise:view'コマンドを打つ様に言っています。（※これに関しては少し詳しく説明していきます。)



##モデルを作成
###Userモデルを作っていきます
モデルの名前は任意なのでcustomerとかでも大丈夫です。

```
$ rails g devise User
```
作られるファイル一覧

[![Image from Gyazo](https://i.gyazo.com/332efd2d1a5bca3a1838539403915189.png)](https://gyazo.com/332efd2d1a5bca3a1838539403915189)

migrationファイルが作成されるので追加したいカラムがある場合は追加してください。
後でカラムを追加する事も可能です。

```ruby:devise_create_users.rb
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ファイルにデータを聞き込んであげましょう。

```ruby:seeds.rb
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と同じですが)

```ruby:applicationController.rb
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に関して(英語)](https://github.com/plataformatec/devise#strong-parameters)


##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が変更されない場合は下記を記述してみてください。
```ruby:config/initializers/devise.rb
config.scoped_views = true
```

##deviseに対応したControllerのカスタマイズ

```
$ rails g devise:controllers users
```
これでdeviseのUsersControllerをインストールできます。

作られたコントローラーが使えるようroutes.rbを編集していきます。

```ruby:routes.rb
  devise_for :users, controllers: {
    registrations: 'users/registrations',
    sessions     : 'users/sessions'
  }
```

>[ルーティングのカスタマイズの詳細はこちら](https://qiita.com/kumatarousuke/items/240c1cc14543d1e1c33e)

[![Image from Gyazo](https://i.gyazo.com/1d7df3e41769260f8345a7b5bc07fe98.png)](https://gyazo.com/1d7df3e41769260f8345a7b5bc07fe98)

##sign_in, sign_out後のpath指定

ログイン/ログアウト後にpathを変更したい事があると思います。
デフォルトだとログイン後はrootパスに飛びます。

```ruby:applicationController.rb
 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のモデルが一つだけでなく２つ以上ある場合はadmin画面でsign_inした時も上に記述したpathにリダイレクトされることになるのでオーバーライドする必要があります。
この様な書き方も出来るだけで他にも方法はあるので自分の用途に合わせて調べてみてください。
[参考にした記事(英語）](https://github.com/plataformatec/devise/wiki/How-To:-Change-the-redirect-path-after-destroying-a-session-i.e.-signing-out)

```ruby
  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などがあるみたいです**

ご覧いただきありがとうございました！