1

平台: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

上面定义的验证在创建时可以正常工作,但在更新的情况下我需要实现不同的逻辑。我不想为相同的要求定义两种方法。所以我想根据函数是更新还是创建操作来执行检查。有什么方法可以知道触发验证的操作是更新还是删除?

4

2 回答 2

2

简单的解决方案是定义一个方法来验证它,用一个参数,然后用不同:on =>的调用进行两次验证,然后用参数调用第一个方法。

此外,如果有帮助,您可以使用new_record?which 会告诉您是否正在创建对象(在保存之前)

于 2011-03-23T02:30:37.520 回答
1

验证可以随时运行,而不仅仅是在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
于 2011-03-23T02:35:12.087 回答