homeASCIIcasts

284: Active Admin 

(view original Railscast)

Other translations: En Es Fr Ru

Other formats:

Written by Naomi Fujimoto

今回のエピソードではActive Adminを見ていきます。このgemを使うとRailsアプリケーションに管理用画面を簡単に追加できます。見栄えのする管理用画面を作成できるだけでなく、自由にカスタマイズ可能です。ライブデモで実際に動作する様子を見ることができます。

今回のエピソードでは、既存のRailsアプリケーションにActive Adminを追加します。対象のアプリケーションは簡単なEコマースアプリで、複数の商品があり、それぞれが価格を持ちカテゴリに属します。Active Adminを使って管理用画面を作成して商品を管理できるようにします。

対象のアプリケーション

Active Adminをインストールする

Active Adminはgemとして配布されていて通常の方法でインストールできます。Gemfileに参照情報を追加しbundleコマンドを実行します。このアプリケーションはRails 3.1で作成されるため、Active Adminが依存するsass-rails gemも忘れずにインクルードするようにします。Rails 3.0の環境ではこの問題は存在しないためインクルードする必要はありません。

/Gemfile

gem 'activeadmin'

Bundlerが終了したら、ジェネレータを実行してアプリケーションにActive Adminを追加します。このジェネレータが、実行後に追加で行なわなくてはいけない設定作業についての指示を与えてくれます。開発環境のMailer設定でホストオプションを追加する必要があります。また、root URLを設定することとアプリケーションのレイアウトファイルでnoticealertのフラッシュメッセージを追加することを忘れないようにしてください。

$ rails g active_admin:install
      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. Setup default url options for your specific environment. Here is an example of development environment:

       config.action_mailer.default_url_options = { :host => 'localhost:3000' }

     This is a required Rails configuration. In production it must be 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>

今回のアプリケーションではこれらすべてについて対応したので、次に進みます。

コマンドがマイグレーションをいくつか生成したので、それをここで実行します。

$ rake db:migrate

Active Adminを利用する

Active Adminのドキュメンテーションを見ると、インストール時にユーザが新規作成され、ユーザ名がadmin@example.com、パスワードがpasswordに設定されるとあります。この認証情報を使ってログインします。(ユーザ名とパスワードをカスタマイズしたければ、マイグレーションの実行前にdevise_create_admin_users.rbを編集します。) Railsサーバを起動してhttp://localhost:3000/adminにアスセスするとログインフォームが表示されるので、先ほどの認証情報を使ってログインします。

Active Adminのログイン画面

ログインするとActive Adminのダッシュボードが表示されますが、まだあまり見るべきものはありません。

Active Adminのダッシュボード

商品を管理できるようにしたいので、次のコマンドを実行してProductリソースをActive Adminに追加します。

$ rails g active_admin:resource product
      create  app/admin/products.rb

このジェネレータがアプリケーションのapp/adminディレクトリの下にproducts.rbファイルを作成します。管理用ダッシュボードを再度読み込み直すとProductsリンクが表示されます。このリンクをクリックすると商品を管理するのに必要なものがすべて入ったページが現れます。

商品カタログの管理用画面

このページは、属性によって商品を並べ替えたり絞り込むことができます。さらにActive AdminはCategoryに対してbelongs_toの関係が設定されていることを検知して、商品をカテゴリで絞り込むためのドロップダウンメニューを表示してくれます。これは新しい商品を作成するときにも機能します。それぞれのデータ型によって、カテゴリはドロップダウンリストとして表示され、その他の属性は入力フィールドが表示されます。

新しい商品ページ

この機能は簡単にカスタマイズできます。まず最初に商品カタログページをカスタマイズして、表示される列数を減らします。そのためには、生成された/app/admin/products.rbファイルを修正します。indexメソッドをオーバーライドして、カタログページを変更します。このメソッドにはブロックがあり、そこでcolumnを呼び出してページに表示する列を指定します。

/app/admin/products.rb

ActiveAdmin.register Product do
  index do
    column :name
    column :category
    column :released_at
    column :price
  end
end

商品ページを再度読み込むと、希望する列が表示されています。

商品ページをカスタマイズし、選択した列が表示される

Categoryとの関連が自動的に検知されて、それぞれの商品に正しいカテゴリが表示されています。

カスタマイズをさらに進めて、columnの1つ目の引数としてタイトルを渡して列のタイトルを変更します。この方法で、released_atフィールドの名前を変更します。

/app/admin/products.rb

ActiveAdmin.register Product do
  index do
    column :name
    column :category
    column "Release Date", :released_at
    column :price
  end
end

列の値を変更したい場合は、columnにブロックを渡します。価格フィールドには今のままでは通貨記号が表示されていないので、これを修正します。columnメソッドはブロックをとることができ、それを追加することで現在のモデルインスタンス(この例ではProduct)がブロックに渡されます。そしてブロックから返される値がその列に表示されます。ここでヘルパーメソッドにアクセスすることができるので、number_to_currencyを使って価格を正しく表示できます。

/app/admin/products.rb

ActiveAdmin.register Product do
  index do
    column :name
    column :category
    column "Release Date", :released_at
    column :price do |product|
      number_to_currency product.price, :unit => "&pound;"
    end
  end
end

ページを再度読み込むと、タイトルが「発売日(Release Date)」に変わり、商品の価格が正しい通貨の表記で表示されています。

価格の列が通貨の値として表示される

価格フィールドから返される値をカスタマイズしているので、このフィールドは並べ替えることができなくなりました。また各項目の編集と削除のリンクもなくなっています。これを修正します。ブロックを使って値をカスタマイズする場合は、常に合わせて:sortableオプションでActive Adminに対して並び替えの方法を指定するようにします。この修正を行い、加えてdefault_actionsを呼び出して編集と削除のリンクを元のように表示させます。

/app/admin/products.rb

ActiveAdmin.register Product do
  index do
    column :name
    column :category
    column "Release Date", :released_at
    column :price, :sortable => :price do |product|
      number_to_currency product.price, :unit => "&pound;"
    end
    default_actions
  end
end

価格フィールドには通貨記号が表示されるようになりましたが、右寄せされていたらより見やすいでしょう。これはCSSを使って対応可能ですが、そのためにはまず列を参照する方法が必要です。Active AdminはMarkabyによく似たHTML生成の方法を提供します。必要な作業は、メソッドを呼び出して生成したいタグの名前を指定するだけです。:classオプションを一緒に指定して、CSSから参照できるようにします。

/app/admin/products.rb

ActiveAdmin.register Product do
  index do
    column :name
    column :category
    column "Release Date", :released_at
    column :price, :sortable => :price do |product|
      div :class => "price" do
        number_to_currency product.price, :unit => "&pound;"
      end
    end
    default_actions
  end
end

これでactive_admin.css.scssファイルを修正してこの列のスタイルを変えることができます。

/app/assets/stylesheets/active_admin.css.scss

// Active Admin CSS Styles
@import "active_admin/mixins";
@import "active_admin/base";

// To customize the Active Admin interfaces, add your
// styles here:
.price {
  text-align :right;
}

価格の列が正しく右寄せされました。

価格の列が正しく右寄せされた

スコープ

Active Adminのもう一つの優れた機能がスコープです。あらかじめ用意されたフィルタのように動作し、2段階の作業で作成できます。まずproductsのActive Adminの設定ファイルでスコープの呼び出しを追加し、スコープの名前を渡します。

/app/admin/products.rb

ActiveAdmin.register Product do
  scope :unreleased
  index do
    column :name
    column :category
    column "Release Date", :released_at
    column :price, :sortable => :price do |product|
      div :class => "price" do
        number_to_currency product.price, :unit => "&pound;"
      end
    end
    default_actions
  end
end

次にProductモデルにそのスコープを記述します。

/app/models/product.rb

class Product < ActiveRecord::Base
  belongs_to :category
  scope :unreleased, where(:released_at => nil)
end

商品の管理用画面を再度読み込むと、スコープのリストが表示されています。クリックすると、そのスコープでフィルタがかけられた商品のリストが表示されます。

unreleased(未発売)スコープでフィルタがかかった商品リスト

ダッシュボードをカスタマイズする

次にダッシュボードのカスタマイズ方法を見ていきます。デフォルトでは空になっているので、最近の商品を表示するように修正します。そのために/app/admin/dashboards.rbファイルを編集します。このファイルのコメントに役に立つドキュメントがあり、いろいろなカスタマイズ方法が説明されています。

ダッシュボードにセクションを追加するにはsectionメソッドを使用します。表に最近の商品をリスト表示したいのですが、そのためにはtable_forコマンドを使用します。そのブロックで、商品カタログの管理用画面をカスタマイズしたときと同じ方法で、表示したい列をcolumnを使って指定します。また、すべての商品を表示するページへ戻るためのリンクも追加します。

/app/admin/dashboards.rb

ActiveAdmin::Dashboards.build do
  section "Recent Products" do
    table_for Product.order("released_at desc").limit(5) do
      column :name
      column :released_at
    end
    strong { link_to "View All Products", admin_products_path }
  end
end

ダッシュボードを再度読み込み直すと、最新発売された商品5件がリンクと一緒に表示されます。

ダッシュボードに最新の商品が表示される

一覧中の各商品にそれぞれの管理用画面へのリンクがあればより便利でしょう。そのためには、価格の列を編集したときのように、columnメソッドにブロックを渡します。

/app/admin/dashboards.rb

ActiveAdmin::Dashboards.build do
  section "Recent Products" do
    table_for Product.order("released_at desc").limit(5) do
      column :name do |product|
        link_to product.title, admin_product_path(product)
      end
      column :released_at
    end
    strong { link_to "View All Products", admin_products_path }
  end
end

link_toにはパスを定義するより簡単な方法があります。admin_product_path(product)を使う代わりに、配列で1個目の要素にシンボルを、2個目にproductを指定して渡します。

link_to product.title, [:admin, product]

ダッシュボードを再度読み込むと、各商品のタイトルがリンクとして表示されます。リンクのひとつをクリックすると、その商品の管理ページが開きます。

スタイルシートを修正する

Active AdminをRails 3.1の環境で利用する場合に注意しなくてはいけない問題があり、トップページに戻るとそれを確認できます。

トップページのスタイルがおかしい

Active Adminのスタイルシートがすべてのページにインクルードされているため、ページの体裁が前と違って表示されてしまいます。Rails 3.1では、 application.cssマニフェストファイルのrequire_tree .の行の影響で、デフォルトではすべてのスタイルシートがインクルードされます。これは希望する形ではないので、アプリケーションのスタイルシートをより細かく制御できるように、とりあえずこの行を削除してしまうのがいいでしょう。メインのアプリケーションにもう一つのスタイルシートがあるだけなので、require_tree .をrequire productsに置き換えます。

/app/assets/stylesheets/application.css

/*
 * This is a manifest file that'll automatically include all the stylesheets available in this directory
 * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
 * the top of the compiled file, but it's generally better to create a new file per style scope.
 *= require_self
 *= require products 
*/

/* Rest of file omitted */

より優れた解決策は、SASSのimportコマンドに切り替える方法です。アプリケーションのメインのCSSファイルのファイル名に拡張子の.scssを追加してSASSに切り替えます。その上でファイルの最初にあるマニフェスト(上のコードで示した部分)を削除して、ファイルの最後にimportコマンドを追加します。

/app/assets/stylesheets/application.css.scss

/* Styles omitted */

@import "products";

ここでトップページを再度読み込むと、正しいスタイルシートだけが読み込まれるので、ページは正しく表示されます。

グローバル設定

Active Adminには/config/initializersディレクトリにもう一つの設定ファイルがあります。今回のエピソードの残りを使って、これを見ていきます。ファイルには多くの設定オプションが含まれ、そのほとんどはコメントアウトされています。唯一有効になっているのが管理用サイトのタイトルで、これを変更してみます。

/config/initializers/active_admin.rb

ActiveAdmin.setup do |config|

  # == Site Title
  #
  # Set the title that is displayed on the main layout
  # for each of the active admin pages.
  #
  config.site_title = "Eifion's Store"

  # Other configuration options omitted.
end

変更を反映させるためにサーバを再起動すると、新しいタイトルが表示されます。

新しいタイトルが表示された

今回のエピソードは以上です。今回触れることができなかった点がたくさんあるので、ドキュメンテーションを参照してその他の機能を確認することをお勧めします。Active Adminのすべての画面は目的に合うように外観と機能をカスタマイズできるので、Railsアプリケーションに管理機能を付加したい場合には強力な解決策になります。