【问题标题】:Propagating Model#save across all ActiveModel associations在所有 ActiveModel 关联中传播模型#save
【发布时间】:2014-06-27 01:58:25
【问题描述】:

我有以下几点:

class User < ActiveRecord::Base
  has_one :blog
end

class Blog < ActiveRecord::Base
  belongs_to :user
end

如果我这样做:

@user = User.new
@blog = Blog.new

@blog.title = 'hi'
@user.blog = @blog

@user.save

为什么/如何在我不保存@blog 对象的情况下将@blog 对象保存到数据库? 例如,如果我从上面的例子继续:

@user.reload
@user.blog.title
#=> 'hi'

它神奇地将@blog 保存到数据库中!

奇怪的是,如果我的@blog 有其他关联,它似乎并没有将它们保存到数据库中。

这背后的一般行为/逻辑是什么?我的@blog 有其他关联,我希望能够简单地调用@user.save 并让它保存所有 关联。我该怎么做?

【问题讨论】:

    标签: ruby-on-rails activerecord activemodel


    【解决方案1】:

    当未指定autosave 选项时,行为是“自动保存”关联,即autosave 选项默认为true,条件为“保存了新的关联记录,但更新的关联是未保存”。

    以下来自 Rails API 文档“Active Record Autosave Association”的描述清楚地解释了此功能:

    AutosaveAssociation 是一个自动处理的模块 保存其父项时保存关联的记录。此外 保存时,它还会销毁标记为的任何关联记录 破坏。 (参见 mark_for_destruction 和marked_for_destruction?)。

    保存父级、它的关联以及标记的销毁 关联,都发生在一个事务中。这不应该离开 数据库处于不一致的状态。

    如果任何关联的验证失败,它们的错误消息 将应用于父级。

    请注意,这也意味着标记为销毁的关联不会 直接销毁。然而,它们仍将被标记为 破坏。

    请注意,autosave: false 与不声明 :autosave 不同。什么时候 :autosave 选项不存在,那么新的关联记录是 已保存,但未保存更新的关联记录。

    如果您不希望在创建/更新或销毁父对象时保存或销毁关联对象,则在声明关联时指定autosave: false

    class User < ActiveRecord::Base
      has_one :blog, autosave: false
    end
    

    这样,当创建 user 时,您将看不到它与 blog 的关联已保存。您必须在关联的 blog 实例上手动调用 save 来保存它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-24
      • 1970-01-01
      • 1970-01-01
      • 2011-10-04
      • 1970-01-01
      • 2018-02-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多