0

我有一个协会,如:

class Contact
  has_many :addresses
  has_many :email_addresses
  has_many :phone_numbers
end

我想将所有记录(地址、电子邮件和电话)保存在一次save声明中。为此,我编写了以下代码。

contact = Contact.new(contact_params)
contact.addresses.build(address_params1)
contact.addresses.build(address_params2)
contact.email_addresses.build(email_params1)
contact.email_addresses.build(email_params2)
contact.phone_numbers.build(phone_params1)
contact.phone_numbers.build(phone_params2)
contact.save

它确实保存了联系人,但不保存其他记录。我在这里想念什么?

注意:我没有使用任何形式来保存数据。我正在导入数据。

4

2 回答 2

0

首先,在我看来,你不能那样做。

  • 如果要保存地址,则需要每个地址的 contact_id。
  • 而且,当您保存接触时,rails 将首先验证接触和所有子对象。这意味着 contact.valid?必须为真才能保存任何记录。
  • 由于联系人在保存到数据库之前没有 id,因此任何地址中的 contact_id 都是空的。因此,contact.valid?只要您需要同时创建新联系人及其子对象 ,将始终为假
  • 总结一下,这里是rails的步骤:
    1. 验证联系人本身,成功!(注意:已保存注释)
    2. 验证每个contact.addresses的地址,未提供contact_id,失败!

二、我对你的问题的建议

关于您的问题“它确实保存了联系人,但不保存其他记录。”,您需要告诉 rails 您要保存子对象(如下所示)。否则,rails 将忽略其他对象。然而,即使你这样做了,你也会遇到我上面描述的问题。

#contact.rb
accepts_nested_attributes_for :addresses
...

我的建议:你可以使用事务。

  1. 创建联系人
  2. 构建所有子对象
  3. 再次保存联系人

代码示例:

#contacts_controller.rb
Contact.transaction do
  contact = Contact.new(contact_params)
  contact.addresses.build(address_params)
  ...
  contact.save
end
于 2013-11-19T00:52:54.143 回答
0

添加validates_associated您的contact模型,然后检查

validates_associated :addresses, :email_addresses, :phone_numbers
于 2013-08-02T11:54:28.017 回答