48
  1. 我知道它会autosave: true根据https://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html保存关联

  2. 我知道它会保存像这样构建的关联

    book = Book.new(name: 'foo') book.authors.build(name: 'bar') #has_many book.save

或喜欢

book = Book.new(name: 'foo')
book.build_author(name: 'bar') #has_one
book.save
  1. 我认为关联在分配或添加时也会被保存

    book = Book.new(name: 'foo') book.author = Author.new(name: 'bar') book.save

或者

book = Book.new(name: 'foo')
book.authors << Author.new(name: 'bar')
book.save

但是,我有一个复杂的错误,它涉及到我希望它不会自动保存的东西。因此,我想通过检查book来进行调试,以验证我认为将要保存的内容实际上会被保存。

TL; 博士;保存关联时检查什么内部状态?我假设一个模型有一个内部实例变量,就像associations_to_save在创建关联时添加的那样。然后,当模型被保存时,它会遍历这些关联并保存它们。

4

3 回答 3

38

不幸的是,没有像 associations_to_save 这样的东西。但是有一些规则说明什么时候保存什么。你可以在这里找到这些:http: //guides.rubyonrails.org/association_basics.html。分数:4.1.5 (belongs_to)、4.2.5 (has_one)、4.3.4 (has_many) 和 4.4.4 (habtm)。

更新:

在 has_many 关联的情况下,如果 child.new_record? 返回 true(孩子尚未保存到 db),或者需要更新 foreign_key 列。这就是为什么:

  1. 将对象添加到已保存父级上的关联确实会保存新子级。
  2. 将对象添加到未保存的父节点上的关联不会保存(没有外键值)
  3. 如果正在保存未保存的父对象并且在关联缓存中有一些子对象,则保存这些对象以更新 foreign_key。
于 2013-09-09T16:54:42.433 回答
4

不确定这是否对其他人有帮助,但我最近在 Rails 5.2 中遇到了类似的问题。

当尝试将对象保存 2 层深时,如果已保存顶层和第一级对象,我的测试将失败。IE。

book_cover.persisted? == true
book_cover.book.persisted? == true

page = book_cover.book.pages.new

page.persisted? == false

# After saving the top level object
book_cover.save
page.persisted? == false

# After saving the immediate parent of page
book_cover.book.save
page.persisted? == true

由于父“书皮”不是新对象“页面”的直接父对象,因此保存“书皮”实际上并没有最终保存“页面”对象。

根据情况,我只是在“book”对象上明确调用 save 来保存所有子对象。

于 2019-03-14T18:12:30.687 回答
0

我想我的回答对提问者来说太晚了(当保存活动记录关联时我不会直接回答)但是有一些方法可以帮助深入了解对象的关联及其状态——比如changed_for_autosave?甚至(私有)方法像nested_records_changed_for_autosave?autosave_association.rbAPI / 文档)的一部分)或(也是私有的)association_instance_get(内部associations.rb)。

nested_records_changed_for_autosave?但是,当它通过加载到内存中的嵌套自动保存关联时要小心(不加载任何新关联!)

这些也可能与一些反射类方法(如reflect_on_aggregationreflect_on_all_aggregationsreflect_on_all_associationsreflect_on_all_autosave_associationsreflect_on_associationreflections用于进一步文档的 API)结合使用,用于自动化关联检查过程,如下所示:

self.class.reflect_on_all_autosave_associations #=> reflections
association_instance_get(reflection.name) #=> association
association.target #=> actual associated object(s)
object.changes #=> e. g. { "name" => ["bill", "bob"] }

使用target(似乎没有很好地记录(此处此处简要提及))返回and的关联对象,或and的关联对象的集合#belongs_to#has_one#has_many#has_and_belongs_to_many

(我没有提供可用的代码,因为需要更多的思考来检查空数组、零值等等。)

在这些关联的对象方法上,如new_record?marked_for_destruction?changes存在。

于 2021-04-28T16:13:17.463 回答