【Rails】devise_invitableで招待メールからパスワード登録したユーザのリダイレクト先を変更する

## deviseとdevise_invitable
deviseとはRailsで作成したアプリケーションへ簡単に認証機能を実装することができるgem（ライブラリ）の一つで、devise_invitableはdeviseに招待機能を追加するgemになります。

### やりたいこと
devise_invitableで招待メールを送信
↓
パスワード設定用の招待メールが送られてくる
↓
パスワード設定
↓
希望の画面にリダイレクトする （今回はこれをやりたい

### 問題点
パスワードを設定すると自動でログインしてくれるのですが、
設定後にroot_pathに遷移してしてしまう。

### ハマったところ
deviseには元来`after_sign_up_path_for`（登録後のリダイレクト先を変更できるメソッド）や
`after_sign_in_path_for`（ログイン後のリダイレクト先を変更できるメソッド）が存在しており、
招待メールからパスワードを設定したのちに自動でログイン状態になっているので同様のやり方でいけると思っていました。

* `after_sign_up_path_for`や`after_sign_in_path_for`については 
[こちらの記事で](https://qiita.com/iwasan06/items/fe0ccc805af592ed00cd)分かりやすくまとめられていました。

### 解決策
ログを読んでみたところ、招待メールからパスワードを登録した際にはライブラリの`invitations_controller`の`update`アクションが呼ばれていることがわかりましたのでGitHubに公開されているコードを確認しました。

```:devise_invitable/app/controllers/devise/invitations_controller.rb 
  # PUT /resource/invitation
  def update
    raw_invitation_token = update_resource_params[:invitation_token]
    self.resource = accept_resource
    invitation_accepted = resource.errors.empty?

    yield resource if block_given?

    if invitation_accepted
      if resource.class.allow_insecure_sign_in_after_accept
        flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
        set_flash_message :notice, flash_message if is_flashing_format?
        resource.after_database_authentication
        sign_in(resource_name, resource)
        respond_with resource, location: after_accept_path_for(resource) // ←ここ
      else
        set_flash_message :notice, :updated_not_active if is_flashing_format?
        respond_with resource, location: new_session_path(resource_name)
      end
    else
      resource.invitation_token = raw_invitation_token
      respond_with_navigational(resource) { render :edit, status: :unprocessable_entity }
    end
  end
```
招待を受けた場合の処理として、ログイン（sign_in）を行なったのち`after_accept_path_for(resource)`でroot_pathに遷移させていることが分かりました。



### 実際の作業
本来、外部ライブラリであるdevise又はdevise_invitableのコントローラーはGem内に記述されているため編集することはできません。
そこで、このcontrollerをオーバーライドしてカスタマイズをしていきます。

まずはオーバーライドするためのファイルを作成します。
``` 
$ rails g controller users/invitations
 ```
ファイルを作成したらGitHubのUpdateアクションの部分をコピペして先ほどの`after_accept_path_for(resource)`の部分を遷移させたいパスに編集します。
```:編集後
module Users
  class InvitationsController < Devise::InvitationsController
    def update
      raw_invitation_token = update_resource_params[:invitation_token]
      self.resource = accept_resource
      invitation_accepted = resource.errors.empty?

      yield resource if block_given?

      if invitation_accepted
        if resource.class.allow_insecure_sign_in_after_accept
          flash_message = resource.active_for_authentication? ? :updated : :updated_not_active
          set_flash_message :notice, flash_message if is_flashing_format?
          resource.after_database_authentication
          sign_in(resource_name, resource)
          respond_with resource, location: users_path(resource)
        else
          set_flash_message :notice, :updated_not_active if is_flashing_format?
          respond_with resource, location: new_session_path(resource_name)
        end
      else
        resource.invitation_token = raw_invitation_token
        respond_with_navigational(resource) { render :edit, status: :unprocessable_entity }
      end
    end
  end
end
```
このとき、`routes.rb`でルーティングの設定を忘れないようにします。
```:routes.rb
  devise_for :users, controllers: {
    sessions: 'users/sessions',
    passwords: 'users/passwords',
    registrations: 'users/registrations',
    invitations: 'users/invitations'
  }
```
これでいけました。