Rails Admin：Custom Actionの追加

## デフォルトのアクションオプション

まずはじめに、Rails Adminのアクションにはこんなデフォルトオプションがあるよ、というご紹介。
オプションのデフォルト値一覧は以下のファイルに書かれている。

[rails_admin/lib/rails_admin/config/actions/base.rb](https://github.com/sferik/rails_admin/blob/master/lib/rails_admin/config/actions/base.rb)


* <b>register_instance_option <span style="color: #00cccc">:collection?</span></b>
  * モデル単位のアクションか
  * デフォルト値: false
* <b>register_instance_option <span style="color: #00cccc">:member?</span></b>
  * オブジェクト単位のアクションか
  * デフォルト値: false
* <b>register_instance_option <span style="color: #00cccc">:controller</span></b>
  * コントローラーアクションの中身
* <b>register_instance_option <span style="color: #00cccc">:bulkable?</span></b>
  * 一括更新か
  * デフォルト値: false
  * モデル単位のアクションのみ
  * コントローラー内で params[:bulk_ids] を処理する必要がある
* <b>register_instance_option <span style="color: #00cccc">:http_methods</span></b>
  * 扱うHTTPメソッド
  * デフォルト値: [:get]

などなど。

## アクションコントローラーの追加

RailsAdminでアクションコントローラーを作成すると、下記のようにタブが追加される。
今回は表示順を変更し、一括で保存するアクションを作成した。

![display_order_tab.png](https://qiita-image-store.s3.amazonaws.com/0/71613/e6977322-f723-629f-9f48-eea651ad5440.png)


### 手順  
 １. lib配下にファイルの作成（今回は display_order_action.rb とした）

```ruby:display_order_action.rb
# 以下２つのファイルを require する
require "rails_admin/config/actions"
require "rails_admin/config/actions/base"
 
module RailsAdmin
    module Config
        module Actions
            class DisplayOrderAction < RailsAdmin::Config::Actions::Base
                RailsAdmin::Config::Actions.register(self)
 
                # カスタムコントローラを作成するため、以下を true にする
                register_instance_option :collection? do
                    true
                end
 
                register_instance_option :bulkable do
                    true
                end
 
                register_instance_option :http_methods do
                    [:get, :put]
                end
 
                # コントローラーアクションの処理
                register_instance_option :controller do
                    Proc.new do
                        if request.get?
                            # 一覧表示　（モデル内容を全て取得）
                            @objects = list_entries(@model_config, :destroy, get_association_scope_from_params, false)
                        elsif request.put?
                            # 表示順の更新
                            objects = list_entries(@model_config, :destroy)
                            params[:products].each do |params_product|
                                object = objects.find(params_product[:id])
                                object.update_attributes(order: params_product[:order])
                            end
                            redirect_to(:back)
                        else
                            raise "エラーメッセージ"
                        end
                    end
                end
            end
        end
    end
end
```


 ２. config/initializers/rails_admin.rb にカスタムアクションの存在を明記する

```ruby:rails_admin.rb
# 先頭で使用するファイルを require する
require Rails.root.join('lib', 'display_order_action.rb')
  
RailsAdmin.config do |config|
    config.actions do
        dashboard                     # mandatory
        index                         # mandatory
        new
        export
        bulk_delete
        show
        edit
        delete
         
        # カスタムアクションを宣言
        display_order_action
    end
end
```



 ３. app/views/rails_admin/main 配下に表示する viewファイルを用意する（今回は display_order_action.html.erb とする）

```ruby:display_order_action.html.erb
<%= form_tag("", method: "put") do %>
    <table class="table table-striped　table-bordered">
        <tr>
            <th>Name</th>
            <th>Order</th>
        </tr>
        <% @objects.each do |object| %>
            <tr>
                <td><%=object.name%></td>
                <td><input type="number" value="<%=object.order%>" name="products[][order]"></td>
                <input type="hidden" value="<%=object.id%>" name="products[][id]"/>
            </tr>
        <% end %>
    </table>
    <%= submit_tag("更新") %>
<% end %>
```



## 所感

苦しみを感じた。

## 参考資料

* <a href="http://qiita.com/joker1007/items/4ac31f081c44634a5e90">
rails_adminをカスタマイズする方法まとめ</a>
* [RailsAdminとの格闘](http://qiita.com/kuboon/items/1d009e2f89729fe5db78)
* [Rails Admin: creating a custom action](http://fernandomarcelo.com/2012/05/rails-admin-creating-a-custom-action/)