Rails APIモードでActive Adminを使おうとした際にハマったので、ハマった原因と同時に使う際の設定を記載しておく。
自動で設定できるようにGemをつくった(2020/07/11追加)
Active Admin Api Only Initializer
※ 新規PJTにしか使えないので注意
使用したレポジトリは下記。
rails-api-with-activeadmin
環境
macOS Mojave Version 10.14.6
目次
- ハマった原因
- Rails APIモードとReactの環境構築
- 環境
- Rails APIモード構築
- Reactの環境構築
- Active Adminの導入
- application_controller.rbとclassの書き換え
- middlewareの追加
- Active Adminのインストール
- 最後に
- 参考
ハマった原因
Rails APIモードとは、JSONをクライアント側に返すだけのRailsアプリケーションなのですが、これが普通のRailsアプリケーションの場合と違って一部のミドルウェアが入っていない状態になります。
詳しくは下記を確認してください。
Rails による API 専用アプリケーション
その状態でActive Adminを入れようとするとlayoutがないというエラーが出ます。
$ bin/rails g active_admin:install
(省略)
/Users/(ユーザー名)/.rbenv/versions/2.5.5/lib/ruby/gems/2.5.0/gems/activeadmin-2.3.1/lib/active_admin/devise.rb:30:in `block in <module:Controller>': undefined method `layout' for ActiveAdmin::Devise::SessionsController:Class (NoMethodError)
このエラーを無視して、サーバーを起動しても同様です。
$ bin/rails s
(省略)
/Users/(ユーザー名)/.rbenv/versions/2.5.5/lib/ruby/gems/2.5.0/gems/activeadmin-2.3.1/lib/active_admin/devise.rb:30:in `block in <module:Controller>': undefined method `layout' for ActiveAdmin::Devise::SessionsController:Class (NoMethodError)
このエラーの原因は、Railsガイドの3.1 アプリケーションを新規作成するに書かれているAPIモードの機能によるものです。
・利用するミドルウェアを通常よりも絞り込んでアプリケーションを起動するよう設定します。
特に、ブラウザ向けアプリケーションで有用なミドルウェア(cookiesのサポートなど)を一切利用しなくなります。
・ApplicationControllerを、通常のActionController::Baseの代わりにActionController::APIから継承します。
ミドルウェアと・同様、Action Controllerモジュールのうち、ブラウザ向けアプリケーションでしか使われないモジュールをすべて除外します。
・ビュー、ヘルパー、アセットを生成しないようジェネレーターを設定します。
このエラーが解決された環境の構築とすでに構築アプリの場合のエラーの解決方法をについて書いていきます。
Rails APIモードとReactの環境構築
Active AdminをRails APIモードとReact環境で入れるという想定で環境を構築していきます。 すでにRails APIモードの環境がある人は次まで飛ばして大丈夫です。
環境
$ ruby -v
ruby 2.5.5p157 (2019-03-15 revision 67260) [x86_64-darwin18]
Rails APIモード構築
Railsのバージョンを指定して、APIモードでインストールします。 ※ bundlerについてはこちらを参照
アプリケーションディレクトリの作成。
$ mkdir rails-api-with-activeadmin
$ cd rails-api-with-activeadmin
$ bundle init
Gemfileに下記を記載後、インストール。
gem 'rails', '~> 6.0.0'
$ bundle exec rails new . --database=mysql --api
※ DBはMySQLで設定していますが、無くても大丈夫です。
Seed管理用にseed-fuを入れておきます。 Gemfileに下記を記載後、インストール。
gem 'seed-fu'
$ bundle install
Rails環境が構築できているか確認します。
$ bin/rails s -p 3001
ブラウザでlocalhost:3001にアクセスし、下記が表示されていればRailsの環境構築終了です。
問題なければ、ctrl + c
でサーバーを止めてください。
Reactの環境構築
React with TypeScriptで導入します。 yarnについてはこちらを参照。
$ yarn create react-app frontend —typescript
$ cd frontend
$ yarn start
下記が表示されていればReact側の環境構築は終了です。
※ 起動画面が新しくなってて少し感動しました。ロゴがぐるぐる回っているのも好きだった。
Active Adminの導入
さて、本題のActive Adminを導入していきます。
application_controller.rbとclassの書き換え
まず、app/controllers/application_controller.rb
をAPIではなくBaseを継承するように書き換えます。これによりApplicationControllerが後述で設定するミドルウェアを使えるようになります。
# 元々はclass ApplicationController < ActionController::API
class ApplicationController < ActionController::Base
end
ただし、このままだとAPIモードにしている意味が無くなってしまうので、app/controllers
にapi_controler.rb
を新たに追加します。
class ApiController < ActionController::API
end
そして、今後コントローラーを作成する際はApplicationController
ではなくApiContoller
を継承する必要があります。
class ExampleController < ApiController
end
既存のアプリで導入する場合は既存のコントローラーの継承元を全て書き換えてください。
middlewareの追加
次にActive Adminを使えるようにするためのmiddlewareの設定をしていきます。
rack, cookie, flashなどがAPIモード側で設定されなくなっているのでそれをいれていきます。
config/application.rb
、config.api = true
以下に下記を追加します。
config.api_only = true
# Active Admin用
config.middleware.use Rack::MethodOverride
config.middleware.use ActionDispatch::Flash
config.middleware.use ActionDispatch::Cookies
config.middleware.use ActionDispatch::Session::CookieStore
Active Adminのインストール
上記でActive Adminを入れる環境が整ったので、Active Adminを入れていきます。
Gemfileにdeviceとactive adminの追加して、インストール。
gem 'activeadmin'
gem 'devise'
$ bundle install
active admin自体をRailsアプリケーションにインストール。
$ bin/rails g active_admin:install
色々ファイルが作成されますが、seed_fuを入れているのでdb/seeds.rb
を削除して、新たにseedファイルを作成します。
$ mkdir db/fixtures/development
$ touch db/fixtures/development/00_admin_users.rb
db/fixtures/development/00_admin_users.rb
に下記を記載して、seedを入れます。
AdminUser.seed(:id,
{id: 1, email: 'admin@example.com', password: 'adminadmin', password_confirmation: 'adminadmin'},
)
$ bin/rails db:create
$ bin/rails db:migrate
$ bin/rails db:seed_fu
サーバーを起動して、localhost:3001/adminにアクセスします。
$ bin/rails s -p 3001
ログイン画面が表示され、
ログインできれば導入完了です。
最後に
これ自体をgem側でなんとかして欲しいなという気持ち。
プルリクチャンスでもある・・・のか?。
参考
A Top Shelf Web Stack—Rails 5 API + ActiveAdmin + Create React App