如 freeze
禁用更新对象值的能力(在一定程度上)。我如何构建一个方法 User.disable_persistence
这将禁用在该对象和关联对象上创建/保存/更新的能力,直接调用(User.save
)和间接调用(User.children << child
)。
是否有 gem 或简单的方法,例如:
class User < ...
def disable_persistence
# magic here (nullify save, and other methods, prevent callbacks etc.)
class_eval :before_save do
errors.add(:base, "Persistence has been disabled for this object")
end
end
end
最佳答案
问题看起来很简单。棘手的部分是 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
注意事项:
一个。实例将响应:
-
#disable_persistence
-
#enable_persistence
-
#persistence_disabled?
B.该类将响应:
-
#disable_persistence
-
#enable_persistence
-
#persistence_disabled?
C.有一个 protected
before_save
检查实例是否可以持久化的方法。它检查是否启用了实例和类持久性。如果任何一个被禁用,则不允许实例持续存在。
D.该功能自动包含在所有 ActiveRecord::Base
中类。这是上面的最后一行。你可能不想要那样。如果您不想那样,您必须调用 include DisablePersistence
在你所有的ActiveRecord::Base
您想要此功能的类(class)。
E.在我链接到的 Rails 项目中,我有一个 initializer
那require
s 包含此代码的文件。查看 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
我希望以上内容能回答您的问题,或者至少在某种程度上有所帮助。
关于ruby-on-rails - rails : how to disable persistence of object temporarily?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17889777/