如同,freeze
禁用更新对象值(一定程度)的能力。我如何构建一个方法User.disable_persistence
,该方法将禁用在该对象和关联对象上创建/保存/更新的能力,这些对象直接调用(User.save
)和间接调用(User.children << child
)。
是否有宝石或简单的方法,如:
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
答案 0 :(得分:2)
如果设置为false,您可以添加before_save
过滤器来检查重定向到根网址的布尔字段(例如editable
)的值。该块将在调用create/save/update
方法之前结束。
答案 1 :(得分:2)
问题似乎很简单。但棘手的部分是它的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?
℃。有一个protected
before_save
方法可以检查实例是否可以持久化。它检查是否启用了实例和类持久性。如果禁用任何,则不允许实例持久。
d。该功能自动包含在所有ActiveRecord::Base
类中。这是上面的最后一行。你可能不希望这样。如果您不希望这样,则必须在您希望使用此功能的所有include DisablePersistence
课程上致电ActiveRecord::Base
。
电子。在我链接到的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
我希望以上回答你的问题,或者至少在某种程度上有所帮助。
答案 2 :(得分:1)
您可以创建一个事务并为回滚抛出任何更改的异常。