Rails "Можно ли узнать, что операция (обновление, создание) выполняется в рамках метода валидации? - PullRequest
1 голос
/ 23 марта 2011

Платформа: Rail 3.0 База данных: mysql 5.1

Бизнес-требования: за один раз может быть выпущен только один товар.После возврата выданного товара может быть выдан новый товар того же товара.Одновременно может быть выпущено несколько товаров из разных продуктов.

Чтобы выполнить вышеуказанные бизнес-требования, я проверяю, есть ли уже товар, выпущенный для того же продукта в том же диапазоне дат (проверяя,в моем, где ниже, перекрытие дат).

     class Item < ActiveRecord::Base
         validate :validate_one_item_for_product
         def validate_one_item_for_product
               items = Item.where( "issue_date < ? and return_date > ? and product_id = ?", return_date, issue_date, product_id)
               errors.add( :base, "item already issued for this product, not returned yet") if items.size > 0
         end
     end

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

Ответы [ 2 ]

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

Простое решение состоит в том, чтобы определить метод для его проверки с параметром, а затем иметь две проверки с различными вызовами :on =>, которые в свою очередь вызывают первый метод с параметром.

Также, если это поможет, вы можете использовать new_record?, который сообщит вам, создается ли объект (до того, как он будет сохранен)

1 голос
/ 23 марта 2011

Валидации можно запускать в любое время, а не только в пределах create, save, update_attributes и т. Д. Поэтому, даже если вы знаете, какой метод вызвал проверку (вы можете взломать с выводом caller), вы не должны его использовать, потому что это может быть что-то совершенно обоснованное, но совершенно неожиданное.

Однако еще не все потеряно. Вы можете проверить, сохранилась ли запись, позвонив по номеру persisted?.

.
 class Item < ActiveRecord::Base
   validate :validate_one_item_for_product, :unless => :persisted?

 private

   def validate_one_item_for_product
     items = Item.where(
       "issue_date < ? and return_date > ? and product_id = ?",
       return_date, issue_date, product_id)
     if items.size > 0
       errors.add(:base,
         "item already issued for this product, not returned yet") 
     end
   end
 end
...