セキュリティ系の勉強・その他開発メモとか雑談. 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"))を書き換えてあげれば良いと思います。