问题看起来很简单。棘手的部分是and indirectly (User.children << child)
它的一部分。User
当父对象 ( ) 是新记录时,这可以很容易地处理。但如果不是,就不会那么容易。这是因为像这样的语句user#children << child
保存了父记录,并且children
当记录user
是新的时,当它不是时不做同样的事情。在后一种情况下,它只保存child
. 这个问题在这个项目上没有自动解决,至少现在是这样。开发人员必须首先禁用child
对象的持久性才能在后一种情况下实现这一点。
查看author_spec.rb
文件。告诉你整个故事非常有帮助。
我为回答您的 SOW 问题而开发的整个项目都在这里:https ://github.com/pmatsinopoulos/disable_persistence
任何想为此做出贡献的人,请随意。
为了方便读者,这里也引用了完成整个技巧的代码:
disable_persistence.rb
文件:
module DisablePersistence
extend ActiveSupport::Concern
def disable_persistence
@persistence_disabled = true
end
def enable_persistence
@persistence_disabled = false
end
module ClassMethods
def disable_persistence
@@class_persistence_disabled = true
end
def enable_persistence
@@class_persistence_disabled = false
end
def persistence_disabled?
@@class_persistence_disabled ||= false
end
def persistence_disabled
persistence_disabled?
end
end
included do
attr_reader :persistence_disabled
alias :persistence_disabled? :persistence_disabled
before_save :can_persist?
after_initialize do |base|
base.instance_variable_set(:@persistence_disabled, false)
end
def can_persist?
!persistence_disabled? && !self.class.persistence_disabled?
end
protected :can_persist?
end
end
ActiveRecord::Base.send :include, DisablePersistence
笔记:
A. 实例将响应:
#disable_persistence
#enable_persistence
#persistence_disabled?
B. 班级将回应:
#disable_persistence
#enable_persistence
#persistence_disabled?
C. 有一种protected
before_save
方法可以检查实例是否可以持久化。它检查是否启用了实例和类持久性。如果有任何被禁用,则不允许实例持续存在。
D. 该功能自动包含在所有ActiveRecord::Base
类中。这是上面的最后一行。你可能不想要那个。如果您不希望这样,您必须调用您想要此功能的include DisablePersistence
所有课程。ActiveRecord::Base
E. 在我链接到的 rails 项目中,我有一个initializer
包含require
此代码的文件。查看config/initializers
. 否则,您将不得不自己要求它。
一些使用示例(假设作者和他们的书):
第一个例子:
author = Author.new
author.disable_persistence
author.save # will return false and nothing will be saved
author.enable_persistence
author.save # will return true and author will be saved
第二个例子:
author = Author.new
author.disable_persistence
book = Book.new
author.books << book
author.save # false and nothing will be saved
第三个例子:
author = Author.new
author.save
book = Book.new
book.disable_persistence
author.books << book # nothing will be saved
第四个例子:
author = Author.new
author.save
book = Book.new
author.disable_persistence
author.books << book # will be saved indeed, because the book has enabled persistency
第五个例子:
author = Author.new
Author.disable_persistence
author.save # will return false and will not save
我希望以上内容能回答您的问题,或者至少在某种程度上有所帮助。