如何在一个事务中保存相关模型?

时间:2013-09-25 11:00:04

标签: ruby-on-rails activerecord ruby-on-rails-4

我有两种模式:

class Customer < ActiveRecord::Base
  has_many :contacts
end

class Contact < ActiveRecord::Base
  belongs_to :customer
  validates :customer, presence: true
end

然后,在我的控制器中,我希望能够同时创建 “一”扫:

@customer = Customer.new
@customer.contacts.build
@customer.save

这个,失败了(不幸的是翻译开启,它转换为 类似于:联系方式:客户不能空白。)

@customer.errors.messages #=> :contacts=>["translation missing: en.activerecord.errors.models.customer.attributes.contacts.invalid"]}

在检查模型时,确实@customer.contacts.first.customernil。不知怎的,这是有道理的,因为@customer没有 已保存,因此没有id

如何构建此类关联模型,然后保存/创建它们,以便:

  • 如果一个模型无效,则不会保留任何模型
  • 错误可以在一个列表中读出,而不是组合 来自所有模型的错误消息,
  • 并保持我的代码简明扼要?

3 个答案:

答案 0 :(得分:2)

来自rails api doc

  

如果要修改关联(而不是仅从中读取),则最好在连接模型的源关联上设置:inverse_of选项。这允许构建相关记录,这些记录将在保存时自动创建适当的连接模型记录。 (参见上面的'关联加入模型'部分。)

只需将:inverse_of添加到关系声明(has_manybelongs_to等),即可active_record以正确的顺序保存模型。

答案 1 :(得分:1)

  • 我想到的第一件事就是 - 摆脱那种验证。
  • 首先想到的是 - 首先保存客户并建立联系。
  • 第三件事:声明关系时使用:inverse_of。也可能有帮助。

答案 2 :(得分:0)

您可以将新创建​​的相关模型保存在单个数据库事务中,但不能只调用save方法。一些ORM(例如LINQToSQL和Entity Framework)可以做到,但ActiveRecord不能。只需使用ActiveRecord::Base.transaction方法即可确保保存两个模型或不保存任何模型。有关ActiveRecord和交易的更多信息http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html