首页 > 解决方案 > 如何在创建/更新时将父模型链接到深度嵌套的模型

问题描述

首先,我试过环顾四周,但如果可能的话,我似乎无法找到关于是否以及如何做到这一点的明确答案。

考虑这些模型

class Group < ApplicationRecord
  belongs_to :owner, class_name: 'User'
  has_many :profiles
  has_many :users, through: :profiles

  validates :name, :owner, presence: true

  accepts_nested_attributes_for :owner
end
class User < ApplicationRecord
  has_many :profiles
  has_many :groups, through: :profiles
  has_many :owned_groups, class_name: 'Group', foreign_key: :owner_id, optional: true

  validates :name, presence: true

  accepts_nested_attributes_for :profiles
end
class Profile < ApplicationRecord
  belongs_to :user
  belongs_to :group

  enum role: [:admin, :moderator, :user]

  validates :user, :group, :role, presence: true
end

是否有任何形状或形式可以让我有一个深度嵌套的形式来创建所有这些,以便发生以下情况?还是真的有必要在创建组/管理员后手动创建配置文件?

deeply_nested_params = params.require(:group).permit(
  :name,
  owner_attributes: [
    :id, # nil on create
    :name,
    profiles_attributes: [
      :id, # nil on create
      :role
    ]
  ]
)
group = Group.new(deeply_nested_params) #=> #<Group>
group.owner.profiles.first.group == group #=> true
# last but not least
group.valid? #=> true

我主要是出于好奇而询问,也是因为我会发现它更“优雅”,以真正group在一行中创建一个(在我的示例中)。

PS:我正在尝试的当前方式的问题group.owner.profiles.first.group是 nil 所以验证失败

PS2:我确实有 3 行(如果您使用{}块代替)1 保存解决方案(有点)有效。但同样,我很好奇需要这种解决方法的解决方案。

group = Group.new(deeply_nested_params) #=> #<Group>
group.owner.profiles.select do |profile| # select because nothing is saved yet so find won't work
  profile.id.nil? # new records only
end.each do |profile|
  profile.group = group
end
group.save!

标签: ruby-on-railsrubyactiverecord

解决方案


推荐阅读