Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
6
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

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

目的

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
6
Help us understand the problem. What are the problem?