目的
UesrオブジェクトがUserInfoオブジェクトをhas_oneで持っており
ActiveAdminのUserオブジェクトの編集画面で、has_oneでつながっているUserInfoオブジェクトを更新したい
この時、状態でUserInfoのレコードが存在しない場合に、UserInfoを新規作成したい場合
ActiveAdminのフォーム設定で少しトリッキーな書き方をする必要がある
サンプルコード
user.rb
class User < ActiveRecord::Base
has_one user_info
# accepts_nested_attributes_for でuserの子要素も連動して作成できるようにする
accepts_nested_attributes_for : user_info
# Userレコードを削除したタイミングでhas_oneでつながっているuser_infoがあれば削除する
after_destroy do
user_info.destroy if user_info.present?
end
省略
end
user_info.rb
class UserInfo < ActiveRecord::Base
belongs_to user
省略
end
ActiveAdminのform要素配下のように設定する
admin/users.rb
form do |f|
f.inputs "User Info" do
f.input :first_name
f.input :last_name
省略
end
# user.user_infoが存在しない場合、UserInfoをブジェクとを初期値として設定しておく
# for 内の配列の一つ目に対象のオブジェクトのクラスを指定、
# 2つ目の配列にhas_oneで繋がっているアソシエーションのオブジェクトを指定する、アソシエーションがnilの場合は||で繋いで新規作成する
f.inputs "UserInfo", for: [:user_info, f.object.user_info || UserInfo.new({user_id: f.object.id, some_attr: "デフォルト値", 省略})] do | user_info |
user_info.input :some_attr
省略
end
f.actions
end
まとめ
ActiveAdminのカスタマイズは闇が深い
カスタマイズが大きくなってきたら素直に普通にViewとControllerを書いたほうが効率が良い気がする