在当前项目中,我有一个名为Box
的模型,用于存储在线商店中的商品。一个方框属于Package
(定义价格,付款条件等),并且有许多Item
和ExtraItem
个对象,其中包含产品和包含在框中的额外优惠。
当客户填写一个包含产品和额外优惠并结账的盒子时,会创建一个类Purchase
的新对象,并引用包含其项目的Box
。
Purchase
有一个名为 total 的属性,它从包含项目的框(在before_validation挂钩上)获取总货币值,并记录即使产品已支付的总金额价格变动。我担心的是,即使在确认并创建购买后,仍然可以更改属于它的框(可以添加/删除项目),创建不反映现实的记录购买时间。
为了防止对框进行更改,我创建了一个挂钩on_initialize和initialize方法的方法,以防止在锁定属性设置为时调用特定的属性更改方法。它的工作原理如下:
def trigger_locked_box_behavior
if locked?
[:items,:extra_items,:garrisons].each { |p| (send("#{p.to_s}")).freeze }
[:package=, :package_id=, :box_behavior_type=, :resource=, :resource_id=, :resource_type=].each do |param|
class_eval do
define_method(param) do |*args|
raise LockedBoxError
end
end
end
end
end
它基本上冻结了关联(一个框有很多项, extraitems 和 garrisons )并重新定义某些方法来引发LockedBoxError异常调用。
由于这似乎按预期工作,我真的担心这种方法会导致意外行为,我正在寻找一种方法来实现相同的效果没有需要覆盖方法我正在做的方式!
你们有没有人知道我可以做到这一点?我真的很感谢你的帮助! :)
答案 0 :(得分:2)
我会使用attr_readonly将您的属性标记为只读。它们将在您创建记录时创建,但在此之后将无法更新。
请参阅http://api.rubyonrails.org/classes/ActiveRecord/Base.html#method-c-attr_readonly
答案 1 :(得分:2)
您也可以使用readonly使记录成为只读。
可以在此处找到文档:http://api.rubyonrails.org/classes/ActiveRecord/Base.html#method-i-readonly-21