RailsAdmin との格闘

# cancan 2.0 に対応させる
http://qiita.com/kuboon/items/fb39639d424ef0a5d463
# 日付の扱いがおかしい
デバッガで追ったら日付が 2014年2Mon8Sun(Sun) とかなってて、なんだこりゃと思ったら、月->Mon、日->Sun の置換が走っていた。Rails本体にはローカライズされた日付を parse する機能は備わってないので誰かが頑張ったのだろうが、不幸にも日本語では曜日を表す「日」「月」が日付の区切り文字を表しているという悲しい現実がある。クソ仕様だと言っても仕方が無い。
parseを頑張るとドツボにハマるので、ここは潔く日本語表記の日付を諦めよう。(ローカライズされた日付を確実に parse できる手法が確立するその日まで。)

最も簡単なのは、 I18n の ja.date.formats.long を削除ないし、日本語を使わない書式にしておくことだ。どうしても long を別の場所で使っていて書き換えられない場合は、

```
field :send_at do
  date_format :custom
end
```
という指定で別のフォーマットを指定出来る。日付フィールドが多くて逐一指定できないよ、という方はモンキーパッチしかない。

``` ruby:config/initializers/rails_admin.rb
module RailsAdmin
  module Config
    module Fields
      module Types
        class Datetime #< RailsAdmin::Config::Fields::Base
          @format = :custom
        end
      end
    end
  end
end
```
みたいにするとうまくいく。

# datetime に default_value 指定しても時刻が反映されない
バグです。

``` ruby
        class Datetime #< RailsAdmin::Config::Fields::Base
          @format = :default
          def self.formatted_time_value
            value = bindings[:object].new_record? && self.value.nil? && !default_value.nil? ? default_value : self.value
            value.nil? ? '' : I18n.l(value, format: localized_time_format)
          end
        end
```
で直った。落ち着いたら本体に pullreq 送ります。

# belongs_to関連のselectフォームのカスタマイズ
http://qiita.com/joker1007/items/4ac31f081c44634a5e90#2-9 にある通り、ここに order 指定してもうまくいかない。どうするかというと、参照先の model (この例だと ParentModel) の config に

```ruby
    list do
      sort_by :start_at
    end
```
と書くとうまくいきます。現状そういうコードなのでこれでうまく行くけど近日中にこの仕様は変更される気がする。

# アクションの追加方法決定版
公式Wiki通りにクラスを作って云々すると、開発時に毎回サーバを再起動しないといけなくて非常にしんどい。
いろいろ四苦hackしたあげく、たどりついたのがこれ。

```ruby:config/initializers/rails_admin.rb
RailsAdmin.config do |config|
  config.actions do
    all # デフォルトアクションを全て読み込む

    member :import do
      # http_methods と visible はここで定義しないと *間に合わない*
      http_methods [:get, :post]
      visible do
        bindings[:abstract_model].model == ::Data
      end
    end
  end
end
```

で、そのアクションを使いたい model の末尾に以下のようにして実体を書く。

```ruby:app/models/data.rb
RailsAdmin.config do |config|
  config.actions do
    find(:import).instance_eval do
      link_icon 'icon-refresh'
      controller do
        Proc.new do
          # development環境での開発がやりやすくなる。やったね！
          if request.get?
            # app/views/rails_admin/main/import.html.haml
            # が render されるので、必要な処理をここに書く。
            # member action なら @object が参照できる
          elsif request.post?
            # 処理を実行する
          end
        end
      end
    end
  end
end
```
controller の書き方は rails_admin gem の ```lib/rails_admin/config/actions/``` が参考になる。
あと、 ```app/views/rails_admin/main/import.html.haml``` を作る。
rails_admin gem の app/views/rails_admin/main/*.haml が参考になる。

# has_secure_password との相性を改善
db上にないカラムでも以下のようにすれば表示できる。

```ruby
     configure :password, :password
     configure :password_confirmation, :password
     edit do
       include_fields :password, :password_confirmation
     end
```
この場合、期待する動作は「パスワード欄がどちらも空だったら変更なし。入力されていてかつ一致していれば変更」なのだが、 rails_admin が余計なお節介をしてくれちゃうので微妙にうまくいかない。
https://github.com/sferik/rails_admin/issues/2150
解決策も既に書いたがここにも一応書いておくと

```config/initializers/rails_admin.rb
module RailsAdmin
  module Config
    module Fields
      module Types
        # https://github.com/sferik/rails_admin/issues/2150
        class Password
          def parse_input(params) end
        end
      end
    end
  end
end
```


# 随時追記中。