これがあれば忘れても大丈夫。gem 'devise' 使い方


# 基本機能

Railsのユーザー登録機能でよく使うgem'devise'ですが、

## gem "devise"のインストール

```ruby:Gemfile
# rails5系なら以下を記述
# For 5.0.x, 5.1.x and 5.2.x
gem 'rails-i18n', '~> 5.1'

gem 'devise'
gem 'devise-i18n'
gem 'devise-i18n-views'
gem 'omniauth-twitter'
```

## deviseの初期設定

```:ターミナル
# gemをインストール
$ bundle install

# deviseのインストール
$ rails g devise:install

# 日本語化するためのymlファイルを作成 > devise.views.ja.ymlが生成される
$ rails g devise:views:locale ja

# ログイン、新規登録などのviewを取得 
$ rails g devise:views

# deviseのコントローラーのカスタマイズ
$ rails g devise:controllers users

# userモデルの作成
$ rails g devise user


```

## 日本語対応させる。

```ruby:config/application.rb
require_relative 'boot'

require 'rails/all'

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module app-name
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 5.2
    config.i18n.default_locale = :ja # 日本語対応
    config.time_zone = 'Tokyo' # 日本時間
    config.active_record.default_timezone = :local # 「データベースに保存されている時刻の値がlocalの時間にする」

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
  end
end



```


## 新規登録のカラム追加

```ruby:application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:username]) # ここにカラム名を追加する。paramsの定義は不要。
  end
end
```

解説
devise_parameter_sanitizerメソッドを使うと,
deviseで設定されている, strong_parametersに対してパラメーターを追加可能

```ruby:
devise_parameter_sanitizer.permit(追加したいメソッドの種類, keys: [追加したいパラメーター名])
```
| 引数の値 | 処理 |
|:--|:--|
| :sign_up | 新規登録時 |
| :sign_in | ログイン時 |
| :account_update | レコードの更新時 |

[参考になるページ](https://qiita.com/tana117/items/60c3e56b6d7b8b9bad1a)

```ruby:application_controller.rb
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    # 新規登録時
    devise_parameter_sanitizer.permit(:sign_up, keys: [:username])
    # ログイン時
    devise_parameter_sanitizer.permit(:sign_in, keys: [:username])
    # 更新時
    devise_parameter_sanitizer.permit(:account_update, keys: [:username])
  end
```


## サインインしていない場合、ログイン画面表示

```ruby:〇〇_controller.rb
before_action :authenticate_user!
```

## ログイン時とログアウト時で表示を変える

```haml:html.haml
%ul.float-right
    - if user_signed_in?
      %li 
        = link_to "マイページ", user_path(current_user.id), class:"btn login"
      %li 
        = link_to "ログアウト", destroy_user_session_path, class:"btn login"
      
    - else
      %li 
        = link_to "ログイン", new_user_session_path, class:"btn login"
      %li
        = link_to "新規登録", registration_users_path, class:"btn registration"
```

## ユーザー情報を取得

```haml:html.haml

 %p current_user.name
```
current_userでユーザー情報を取得できます。

# メール認証


実はマイグレーションファイルにメール認証機能用のカラムがあるので、それを使います。

```ruby:----devise_create_user.rb（マイグレーションファイル）

## Confirmable　下記のコメントアウトを解除する
      t.string   :confirmation_token
      t.datetime :confirmed_at
      t.datetime :confirmation_sent_at
      t.string   :unconfirmed_email # Only if using reconfirmable
```

```:ターミナル
$ rake db:migrate
```

これで追加されます。
すでにmigrate済みでも改めて実行すれば追加されます。

```:ターミナル
$ rails s
```
サーバーを立ち上げ直します。

user.rbに「:confirmable」を付与させて、メール認証機能を利用します。

```ruby:user.rb
class User < ApplicationRecord

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable, :confirmable # ここを追加

end
```

つづいて, 

```ruby:devise.rb
  config.mailer_sender = '-------@gmail.com' #メール認証の送信元アドレスを設定

  # Configure the class responsible to send e-mails.
  config.mailer = 'Devise::Mailer'

```

### 開発環境に記述

最後にdevlopment.rbに下記を追加しています。

```ruby:development.rb
config.file_watcher = ActiveSupport::EventedFileUpdateChecker

  config.action_mailer.default_url_options = {  host: 'localhost', port: 3000 }
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {  
    address: 'smtp.gmail.com',
    domain: 'gmail.com',  
    port: 587,  
    user_name: Rails.application.credentials.gmail[:email],  
    password: Rails.application.credentials.gmail[:password],  
    authentication: :login
  }
```

user_nameにgmailのメールアドレスを追加します。
passwordはアプリパスワードとなります [アプリパスワードの生成方法はこちら](https://qiita.com/ozackiee/items/f260f34db4e5c887460d)
今回はcredentials.ymlで設定しています。

サーバーを再起動します。

### 本番環境用の設定

```ruby:config/environment/development.rb
config.file_watcher = ActiveSupport::EventedFileUpdateChecker

  config.action_mailer.default_url_options = {  host: 'ここにurlまたはElastic IP' }
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {  
    address: 'smtp.gmail.com',
    domain: 'gmail.com',  
    port: 587,  
    user_name: Rails.application.credentials.gmail[:email],  
    password: Rails.application.credentials.gmail[:password],  
    authentication: :login
  }
```

本番環境用で上記を設定していなければ、

```:エラー
Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
```
が表示されます。
メール認証時に認証用のURLを作成して送信しますが、どのURLを元に作成するのか設定しておかないとエラーが発生します。
これが開発環境、本番環境（おそらくテスト環境でも必要）で設定する必要がある。

#### 参考になる記事
[RailsでMissing host to link to!が出たときに。model内でURL組み立てる場合の設定](https://qiita.com/daik/items/41a9bc8dec5ccec37f40)

### それではローカルに戻ります
```:ターミナル
$ rails s
````

これで利用できるようになります。

メールの文章を変更するのは下記ファイルになります

```ruby:views/devise/mailer/confirmation_instructions.html.haml
%p
  -----を利用いただき、ありがとうございます !
%p #{@email}に届いた、下記リンクを押すと登録完了となります
%p= link_to 'リンクをクリックしてメール認証を完了してください', confirmation_url(@resource, confirmation_token: @token)
```

## edit/update

[参考になるページ](https://qiita.com/akr03xxx/items/82ba45f7ef4fdbd5c702)


### プロフィールだけupdateしたい
プロフィールだけ更新したいですが、実際にはパスワードの更新も求められます。
ですから下記を実装してPWの更新を求められないようにします。

####コントローラーを編集

パスワードを更新することが必須になっているので、PWは更新しないように除外します
deviseのコントローラーであるregistrations_controller.rbを編集します

```ruby:registrations_controller.rb
  protected

  def update_resource(resource, params)
    resource.update_without_password(params)
  end
```

update_without_passwordでパスワードはなくてもいいよと設定されます。
この処理はまだ読み込まれませんので、route.rbを編集して読み込まれるようにしましょう。


####route.rbを編集
devise関連のrouteを担う、devise_for :usersにページを追加します。


```ruby:route.rb
Rails.application.routes.draw do
  devise_for :users, controllers: { registrations: 'users/registrations' }
end
```



#### カラムを追加する
updateするためのカラムを追加します。paramsに含める必要があるので、appication_controller.rbで設定されているdeviseのparamsに追記します。

```ruby:application_controller.rb
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    # 新規登録時
    devise_parameter_sanitizer.permit(:sign_up, keys: [:username])
   # 更新時
    devise_parameter_sanitizer.permit(:account_update, keys: [:username, :profile])
  end
```




## form_forからform_withに変換する
https://qiita.com/wonder_meet/items/fac07af1edcd79ad102a


# 参考リンク
[参考になるサイト](https://bbbbruno.qrunch.io/entries/wcNZqbMwA5SRBqQj)
[Railsを日本語にする](https://qiita.com/shimadama/items/7e5c3d75c9a9f51abdd5)
[日本語にする](https://qiita.com/you8/items/921e0dd1210eb0d158df)
[日本語にする参考２](https://qiita.com/ryuuuuuuuuuu/items/48dec280cf8925968c65)
[メール認証](https://bbbbruno.qrunch.io/entries/wcNZqbMwA5SRBqQj)
[【Rails】deviseでURL認証付きのメールを送信してみる](https://qiita.com/ozackiee/items/21fcad4a1564136b9510)
[【Rails】メール送信設定 〜gmail利用〜](https://qiita.com/ozackiee/items/f260f34db4e5c887460d)
[devise メール認証](https://qiita.com/jonnyjonnyj1397/items/e54cac472bbb5d71ea1e)
[[*Rails*] deviseの使い方（rails5版）](https://qiita.com/cigalecigales/items/f4274088f20832252374)