Railsで最速で管理画面を作る！

こんにちは、Ruby を触り始めてやっと3ヶ月経った @enomotodev です。

今回は Rails で ActiveAdmin を使って最速で管理画面を作る方法を紹介したいと思います！

## 環境

- Ruby 2.3.5
- Rails 5.1.4
- MySQL 5.7.20

## ActiveAdmin のインストール

Gemfile に `activeadmin` と `devise` を追加し、`bundle install` します。

```ruby:Gemfile
...
gem 'activeadmin'
gem 'devise'
```

```shell-session
$ bundle install
```

インストールが完了したら ActiveAdmin の generator を実行して ActiveAdmin に必要なファイルを生成します。

```shell-session
$ bin/rails g active_admin:install
Running via Spring preloader in process 9928
      invoke  devise
    generate    devise:install
      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

===============================================================================
      invoke    active_record
      create      db/migrate/20180105014902_devise_create_admin_users.rb
      create      app/models/admin_user.rb
      invoke      test_unit
      create        test/models/admin_user_test.rb
      create        test/fixtures/admin_users.yml
      insert      app/models/admin_user.rb
       route    devise_for :admin_users
        gsub    app/models/admin_user.rb
        gsub    config/routes.rb
      append    db/seeds.rb
      create  config/initializers/active_admin.rb
      create  app/admin
      create  app/admin/dashboard.rb
      create  app/admin/admin_users.rb
      insert  config/routes.rb
    generate  active_admin:assets
Running via Spring preloader in process 9943
      create  app/assets/javascripts/active_admin.js.coffee
      create  app/assets/stylesheets/active_admin.scss
      create  db/migrate/20180105014910_create_active_admin_comments.rb
```

generator で migration ファイルも作成されたので migration を実行します。

```shell-session
$ bin/rails db:migrate
== 20180105014902 DeviseCreateAdminUsers: migrating ===========================
-- create_table(:admin_users)
   -> 0.0132s
-- add_index(:admin_users, :email, {:unique=>true})
   -> 0.0328s
-- add_index(:admin_users, :reset_password_token, {:unique=>true})
   -> 0.0249s
== 20180105014902 DeviseCreateAdminUsers: migrated (0.0713s) ==================

== 20180105014910 CreateActiveAdminComments: migrating ========================
-- create_table(:active_admin_comments)
   -> 0.0247s
-- add_index(:active_admin_comments, [:namespace])
   -> 0.0201s
== 20180105014910 CreateActiveAdminComments: migrated (0.0450s) ===============
```

初期データとしてログイン用のユーザを作成します。

```shell-session
$ bin/rails db:seed
```

`rails s` などして、サーバを起動した後に `http://localhost:3000/admin` にアクセスするとログイン画面が表示されるので、先ほど初期データとして投入した下記のユーザ情報でログインします。

- User: admin@example.com
- Password: password

![スクリーンショット 2018-01-26 10.23.58.png](https://qiita-image-store.s3.amazonaws.com/0/128054/d68a3124-0ef8-d465-7fb3-c19a4ea4111d.png)

これであっという間にログイン機能付きの管理画面が作成されました！

この状態では管理者ユーザの管理しか機能がないので、書籍管理をできるようにしていきたいと思います。

## 書籍管理を作ってみる

### 著者（Author）管理の作成

まずは著者（Author）モデルを generate し、migration を実行します。

```shell-session
$ bin/rails g model Author name:string
$ bin/rails db:migrate
```

`rails g active_admin:resource` コマンドにモデル名を渡すことにより、そのモデルに対する管理ページを作成することができるので、実際に Author モデルの管理ページを作成してみます。

```shell-session
$ bin/rails g active_admin:resource Author
Running via Spring preloader in process 23505
      create  app/admin/authors.rb
```

新しく `app/admin/authors.rb` が作成されたのが確認できるかと思います。

この段階でブラウザで確認してみると画面上部のタブに `Authors` が追加されています。

![スクリーンショット 2018-01-26 10.42.25.png](https://qiita-image-store.s3.amazonaws.com/0/128054/1c877afc-1a9d-f591-b52f-7ee5a76b7ba6.png)

しかし、このまま Author を新規作成しようとすると `ActiveModel::ForbiddenAttributesError` が出てしまいます。

![スクリーンショット 2018-01-26 10.45.57.png](https://qiita-image-store.s3.amazonaws.com/0/128054/52a21357-1f19-9b5d-40b1-790edc087b94.png)

これを解決するには先ほど作成された `app/admin/authors.rb` に `permit_params` を追加する必要があります。これは Rails のストロングパラメータのように、許可したいパラメータのみを記述するメソッドです。

許可したいパラメータは `name` だけなので、`permit_params` に `name` を追加します。

```ruby:app/admin/authors.rb
ActiveAdmin.register Author do
  permit_params :name
end
```

![スクリーンショット 2018-01-26 11.10.56.png](https://qiita-image-store.s3.amazonaws.com/0/128054/2380499a-da17-9aba-2ecb-827528ac1730.png)

これで Author の管理が完成しました！

### 書籍（Book）管理の作成

Author の管理が完成したので、次は書籍（Book）の管理を作成していきたいと思います。

まずはモデルを generate し、マイグレーションを実行し、Author モデルと Book モデルにそれぞれリレーションを定義します。

```shell-session
$ bin/rails g model Book author:references title:string publish_date:date
$ Y
```

```ruby:app/models/author.rb
class Author < ApplicationRecord
  has_many :books
end
```

次に、`rails g active_admin:resource` コマンドに Book モデルを渡して実行し、`app/admin/books.rb` を作成した後に、`permit_params` を設定します。

```
$ bin/rails g active_admin:resource Book
Running via Spring preloader in process 23790
      create  app/admin/books.rb
```

```ruby:app/admin/books.rb
ActiveAdmin.register Book do
  permit_params :author_id, :title, :publish_date
end
```

新規作成画面を見てみると、モデルでリレーションが定義されているので、Author のセレクトボックスにも自動的に値が入っているのが確認できるかと思います。

### フォームのカスタマイズ

新規作成画面や編集画面のフォームは自動的に作られるのですが、ここで、Book 管理のフォームをカスタマイズしてみたいと思います。まずは自動的に作られているフォームと同じものを定義します。

```ruby:app/admin/books.rb
ActiveAdmin.register Book do
  permit_params :author_id, :title, :publish_date

  form do |f|
    f.inputs do
      f.input :author
      f.input :title
      f.input :publish_date
    end
    f.actions
  end
end
```

自動的に作られるフォームの場合 publish_date が年/月/日でそれぞれセレクトボックスになっているので、これを DatePicker に変更してみたいと思います。

```ruby:app/admin/books.rb
ActiveAdmin.register Book do
  permit_params :author_id, :title

  form do |f|
    f.inputs do
      f.input :author
      f.input :title
      f.input :publish_date, as: :datepicker  # ここに追加
    end
    f.actions
  end
end
```

![スクリーンショット 2018-01-26 11.40.33.png](https://qiita-image-store.s3.amazonaws.com/0/128054/2286012b-51c3-f80e-8efd-c8945ac71e14.png)

これで `publish_date` が DatePicker に変更され、登録・編集を行いやすくなりました！

### 一覧ページのカスタマイズ

次は Author の一覧ページを自動的に作られるデフォルトのページから変更し、所属する書籍数を表示できるようにしたいと思います。

まずはデフォルトと同じ表示にしてみます。

```ruby:app/admin/author.rb
ActiveAdmin.register Author do
  permit_params :name

  index do
    selectable_column
    id_column
    column :name
    column :created_at
    column :updated_at
    actions
  end
end
```

ここに所属する書籍数の列も追加したいと思います。

```ruby:app/admin/author.rb
ActiveAdmin.register Author do
  permit_params :name

  index do
    selectable_column
    id_column
    column :name
    column '書籍数' do |author|
      author.books.count
    end
    column :created_at
    column :updated_at
    actions
  end
end
```

![スクリーンショット 2018-01-26 11.46.49.png](https://qiita-image-store.s3.amazonaws.com/0/128054/1f1b9bfa-8bb8-0ef0-7a40-5deba223bc4f.png)

一覧に書籍数の列が追加されているのが確認できました！

### 詳細ページのカスタマイズ

Author の詳細ページをカスタマイズし、所属する書籍一覧テーブルを追加してみたいと思います。

まずは自動的に作られている一覧ページのコードを確認して見ましょう。

```ruby:app/admin/author.rb
ActiveAdmin.register Author do
  # ...

  show do |author|
    attributes_table(*author.class.columns.collect { |column| column.name.to_sym })
    active_admin_comments
  end
end
```

ここにコードを追加し、書籍一覧テーブルを表示させます。

```ruby:app/admin/author.rb
ActiveAdmin.register Author do
  # ...

  show do |author|
    attributes_table(*author.class.columns.collect { |column| column.name.to_sym })
    panel "書籍一覧" do
      table_for author.books do
        column :title
        column :publish_date
      end
    end
    active_admin_comments
  end
end
```

![スクリーンショット 2018-01-26 12.06.16.png](https://qiita-image-store.s3.amazonaws.com/0/128054/87a7df85-3b27-89df-d372-a025cf3e40a0.png)

## まとめ

ActiveAdmin を使って Rails で管理画面を作成しました。

1から自分で管理画面を作成するよりも、かなり高速で管理画面で作ることができたのが確認できたと思います。

さらにカスタマイズしたい場合はドキュメントにも詳しく書いてあるので、皆さんもぜひ ActiveAdmin を試してみてください！