APIモードでRails構築した後からdeviseでログイン画面作ろうとしてドハマリしたので、備忘録も兼ねて記述
ハマるまでの経緯
- Rails + JSフレームワークでSPAを作ろうと考える
- APIサーバー構築のため、Rails5のAPIモードを使用
- 一般公開用ページとは他に、管理者用の管理ページ作成に着手
- ログイン処理周りも全部SPAの枠組みで作ろうとすると認証とか大変だったので、管理ページはRailsに組み込むことにした
- deviseインストール + 初期設定をGithubのReadme見ながら実施
- 管理ページを開こうとするとエラーになって動かない!
実施した対応
## エラーその1
undefined method 'flash' for#<ActionDispatch::Request>
- なんかflashメソッドが見つかんないって怒られてる
- 経緯5.まで実施して一番最初に発生
原因
- Rails5をAPIモードで構築すると、ブラウザ操作に関わるいくつかのミドルウェアがインストールされない。
Rails ユーザー必見!Rais 5の注目新機能と変更点まとめ - インストールされないミドルウェアの中で、flashメソッドが定義されていた。
対策
- 以下の行を追加し、ActionDispatch::Flashがインストールされるようにする。
config/application.rb
config.middleware.use ActionDispatch::Flash
エラーその2
undefined method `protect_against_forgery?' for #<Class>
- ログイン画面(/users/sign_in)にアクセスしようとすると発生
- protect_against_forgery?は
ここの394行目
で定義されている。 - 上記モジュール(RequestForgeryProtection)自体はActionController::Base内でちゃんとincludeされてるっぽい(203〜251行目あたり)。
原因
- Rails5をAPIモードで構築すると、ApplicationControllerの親がActionController::Baseではなく、ActionController::APIになる。
- deviseの各コントローラーは、デフォルトでApplicationControllerを親として継承するようになっている(226・227行目)。
- ActionController::APIは、RequestForgeryProtectionをindludeしていない(111〜143行目)
対策
- deviseの各コントローラーが、ApplicationControllerではなくActionController::Baseを継承するようにする
config/initializes/devise.rb
config.parent_controller = 'ActionController::Base'
ここまで実施してからサーバーを再起動後、/users/sign_inにアクセスするとログイン画面が表示された。