In a current project, I have a model called Box
that stores items from an online store. 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.
Purchase
is created, with a reference to the Box
that contains its items.
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. My concern is that even after a purchase is confirmed and created, the box开发者_JAVA百科 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. 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.
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! :)
You can also make a record become readonly by using readonly!.
Documentation can be found here: http://api.rubyonrails.org/classes/ActiveRecord/Base.html#method-i-readonly-21
I would use attr_readonly to mark your attributes read only. 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
精彩评论