如何防止修改模型?

时间:2011-03-27 00:09:49

标签: ruby-on-rails ruby metaprogramming rails-models

在当前项目中,我有一个名为Box的模型,用于存储在线商店中的商品。一个方框属于Package(定义价格,付款条件等),并且有许多ItemExtraItem个对象,其中包含产品和包含在框中的额外优惠。
当客户填写一个包含产品和额外优惠并结账的盒子时,会创建一个类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异常调用。

由于这似乎按预期工作,我真的担心这种方法会导致意外行为,我正在寻找一种方法来实现相同的效果没有需要覆盖方法我正在做的方式!

你们有没有人知道我可以做到这一点?我真的很感谢你的帮助! :)

2 个答案:

答案 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