开发者

How do I prevent modifications to a Model?

开发者 https://www.devze.com 2023-02-19 19:42 出处:网络
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 object

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.

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.

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

0

精彩评论

暂无评论...
验证码 换一张
取 消