RailsAdmin との格闘

  • 25
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

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

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

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 指定しても時刻が反映されない

バグです。

        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 に

    list do
      sort_by :start_at
    end

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

アクションの追加方法決定版

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

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 の末尾に以下のようにして実体を書く。

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上にないカラムでも以下のようにすれば表示できる。

     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

随時追記中。