LoginSignup
7
7

More than 5 years have passed since last update.

ActiveAdminでhas_oneでアソシエーションしているモデルを親モデルとまとめてデータを更新する方法

Posted at

目的

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を書いたほうが効率が良い気がする

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7