[英]How do I prevent modifications to a Model?
In a current project, I have a model called Box
that stores items from an online store. 在当前项目中,我有一个名为Box
的模型,该模型存储在线商店中的商品。 A box belongs to a Package
(which defines price, payment conditions, etc) and has many Item
and ExtraItem
objects that hold products and extra offers included to the box. 包装盒属于“ Package
(定义价格,付款条件等),并具有许多Item
和ExtraItem
对象,用于容纳包装盒中包含的产品和额外优惠。
When the customer fills a box with products and extra offers and proceeds to checkout, a new object of class Purchase
is created, with a reference to the Box
that contains its items. 当客户用产品和额外优惠填充盒子并进行结帐时,将创建一个类Purchase
的新对象,并引用包含其项目的Box
。
A Purchase
has an attribute named total which gets the total monetary value from the box that contains the items (on a before_validation hook) and keeps record of the total paid even if products prices change. Purchase
具有名为total的属性,该属性从包含项目的框(在before_validation挂钩上)获取总货币值,并且即使产品价格发生变化也保留已支付总金额的记录。 My concern is that even after a purchase is confirmed and created, the box that belongs to it can still be changed (items can be added/removed), creating records that don't reflect the reality at the time of the purchase. 我担心的是,即使在确认并创建购买后,仍可以更改其所属的框 (可以添加/删除项目),创建的记录不能反映购买时的实际情况。
To prevent changes to box, i've created a method that hooks on after_initialize and initialize methods to prevent specific attribute-changing methods from being called if a locked attribute is set to true . 为了防止对box进行更改,我创建了一个方法,该方法挂在after_initialize和initialize方法上,以防止在锁定属性设置为true的情况下调用特定的属性更改方法。 It works as following: 它的工作方式如下:
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
It basically freezes the associations (a box has many items , extraitems and garrisons ) and redefines certain methods to raise a LockedBoxError exception when called. 它基本上冻结了关联(一个盒子包含许多物品 , 额外 物品和驻军 ),并重新定义了某些方法,以在调用时引发LockedBoxError异常。
As this seems to be working as intended, i'm really worried that this approach can cause unexpected behavior and i'm looking for a way to achieve the same effect without the need to override methods the way i'm doing! 由于这似乎按预期工作,我真的很担心这种方法会导致意外的行为,我正在寻找一种方法来实现相同的效果, 而无需覆盖我正在做的方法!
Do you folks know any way i can possibly do this? 你们知道我有什么办法吗? I really appreciate your help! 非常感谢您的帮助! :) :)
I would use attr_readonly to mark your attributes read only. 我将使用attr_readonly将您的属性标记为只读。 They will be created when you make the record, but will not be updatable after that. 它们将在您创建记录时创建,但此后将无法更新。
See http://api.rubyonrails.org/classes/ActiveRecord/Base.html#method-c-attr_readonly 参见http://api.rubyonrails.org/classes/ActiveRecord/Base.html#method-c-attr_readonly
You can also make a record become readonly by using readonly!. 您也可以使用readonly!使记录变为只读。
Documentation can be found here: http://api.rubyonrails.org/classes/ActiveRecord/Base.html#method-i-readonly-21 可以在这里找到文档: http : //api.rubyonrails.org/classes/ActiveRecord/Base.html#method-i-readonly-21
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.