Как предотвратить изменения в модели? - PullRequest
0 голосов
/ 27 марта 2011

В текущем проекте у меня есть модель с именем Box, в которой хранятся товары из интернет-магазина.Ящик принадлежит к Package (который определяет цену, условия оплаты и т. Д.) И содержит множество объектов Item и ExtraItem, которые содержат продукты и дополнительные предложения, включенные в коробку.
Когда клиент заполняет коробкутовары и дополнительные предложения и приступает к оформлению заказа, создается новый объект класса Purchase со ссылкой на Box, который содержит его элементы.

A Purchase имеет атрибут с именем total , который получает общую денежную стоимость из ящика, содержащего элементы (в ловушке before_validation), и ведет учет общей суммы, выплаченной, даже если продуктыцены меняются.Меня беспокоит то, что даже после того, как покупка подтверждена и создана, принадлежащая ей коробка все еще может быть изменена (элементы могут быть добавлены / удалены), создавая записи, которые не отражают реальность в то времяпокупки.

Чтобы предотвратить изменения в ящике, я создал метод, который подключает методы after_initialize и инициализируют, чтобы предотвратить вызов определенных методов изменения атрибута, если атрибут locked установите true .Он работает следующим образом:

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 и гарнизонов ) и переопределяетопределенные методы для вызова исключения LockedBoxError при вызове.

Поскольку это, кажется, работает как задумано, я действительно обеспокоен тем, что этот подход может вызвать неожиданное поведение, и я ищу способ достижения того же эффекта без необходимость переопределять методы так, как я делаю!

Вы знаете, как я могу это сделать?Я очень ценю вашу помощь!:)

Ответы [ 2 ]

2 голосов
/ 27 марта 2011

Вы также можете сделать запись доступной только для чтения, используя readonly!.

Документацию можно найти здесь: http://api.rubyonrails.org/classes/ActiveRecord/Base.html#method-i-readonly-21

2 голосов
/ 27 марта 2011

Я бы использовал attr_readonly, чтобы пометить ваши атрибуты только для чтения.Они будут созданы при создании записи, но после этого не будут обновляться.

См. http://api.rubyonrails.org/classes/ActiveRecord/Base.html#method-c-attr_readonly

...