セキュリティ系の勉強、その他開発メモとか雑談. GithubはUnity触っていた頃ものがメイン Twitterフォローもよろしくです

【Rails】Administrateで独自の属性型を定義しReadonly等に対応する

目的

administrateの管理画面での属性の表示を色々といじりたいときに、新しいクラスを作成して、対応する方法です。例えば、readonlyな表示をしたり、ラジオボタンに対応したりなどです。下のような感じ。今回はreadonlyを例にしてやります。


f:id:thinline196:20191007171742p:plain
f:id:thinline196:20191007171746p:plain

完成系

HogeDashboardのidを下のように指定すれば、readonlyな表示になる。

class HogeDashboard < Administrate::BaseDashboard

  ATTRIBUTE_TYPES = {
    id: Field::NumberField.with_options(readonly: true),
  }
end



土台をadministrateより生成する

http://administrate-prototype.herokuapp.com/customizing_attribute_partials 上のページにあるように、既に用意されているNumberを継承して生成します。4つのファイルが生成されます。(上のページの先の説明と若干違う)

$ bin/rails g administrate:field number
      create  app/fields/number_field.rb
      create  app/views/fields/number_field/_show.html.erb
      create  app/views/fields/number_field/_index.html.erb
      create  app/views/fields/number_field/_form.html.erb



NumberFieldクラス

新たにreadonly?というインスタンスメソッドを追加します。(あとで自分で呼び出すコードを書くので、特に決まった名前はないです。)これは、ダッシュボードで指定する:readonlyの値をoptionsから取り出して返します。(この辺りの動作はfetch参照)

# app/fields/number_field.rb
require "administrate/field/base"

class NumberField < Administrate::Field::Base
  def to_s
    data
  end

  # ここから新規実装
  def readonly?
    options.fetch(:readonly,false)
  end
end



viewの部分

先ほど生成した残りの3つのファイルが表示部分を担当しております。今回はreadonlyということで、editのページでのみいじれないようにすれば、index等のページはそのままでも問題はないでしょう。なお私はslimを使っているのでerbの方とは若干書き方が異なります。

# app/views/fields/number_field/_form.html.slim
.field-unit__label
  = f.label field.attribute
.field-unit__field
  - if field.readonly?
    = f.text_field(field.attribute,disabled: "disabled")
  - else
    = f.text_field field.attribute


ifで先ほど実装したreadonly?を呼び、readonlyダッシュボードで指定されているか調べます。trueであれば、フィールドをreadonly(見た目の都合上disabledを使用しました)で返し、そうでなければ普通のNumberで描画します。

ラジオボタンなど他の実装であっても、ダッシュボードでwith_optionsにより適切な値を設定してあげ、それに対応する描画部分を(今回であればf.text_field(field.attribute,disabled: "disabled"))を書き換えてあげれば良いと思います。