はじめに
ActiveAdmin で管理画面を作成した際に、NestedAttributes のリソースを更新する方法を調べて実装した時のメモ。
実装内容
User が複数の Picture (PaperClip を使用) を持つ際に、それを ActiveAdmin で追加、更新、削除を行えるようにする
サンプルソース
使用するモデル
class User < ActiveRecord::Base
  has_many :pictures, as: :holder, dependent: :destroy
  accepts_nested_attributes_for :pictures, limit: 3, allow_destroy: true
  validates :email, :name, presence: true
end
class Picture < ActiveRecord::Base
  WIDTHS = %i{640 200 142 80}
  STYLES = WIDTHS.map {|width| [:"w#{width}", "#{width}x>"]}.to_h
  belongs_to :holder, polymorphic: true
  has_attached_file :image, { styles: STYLES } # 同時に複数のサイズの写真を保存してくれる
  validates_attachment_size :image, less_than: 1.5.megabytes
  validates_attachment_content_type :image, content_type: %w{image/jpeg image/jpg image/png image/gif}
end
PaperClip の設定は省略します
ActiveAdmin のリソースファイル
ActiveAdmin.register User do
  # 作成/編集
  form do |f|
    inputs  do
      input :name
      input :email
      has_many :pictures, heading: "プロフィール画像", allow_destroy: true, new_record: true do |u|
        u.input :image, :as => :file, input_html: { accept: 'image/*' },
          :hint => u.object.new_record? ? "プロフィール画像を指定して下さい" : u.template.image_tag(u.object.image.url(:w80))
      end
    end
  end
  permit_params :email, :name, { pictures_attributes: [ :image, :id, :_destroy ] }
end
サンプルの説明
has_many
allow_destroy は削除可能か否かのフラグで、true にすると各 picture 毎に削除するというチェックボックスが表示される
new_record は、新しいレコード(リソース) の追加を許可するかのフラグで、true にすると 新規に "#{モデル名}" を追加するのボタンが表示され、押下すると同じ input タグが追加される
input
最初の引数は、picture の image なので、:imageとし、画像ファイルのため、 as で file を指定
input_html の説明はこちら
hint は、ファイル選択ボタンの下部に表示するメッセージで、今回は、ユーザー情報変更画面でユーザーにプロフィール画像が存在する場合に、その画像の image タグを表示し、存在しない場合は、メッセージを表示