开发者

Rails" Is it possible to know operation(update, create) being performed within validation method?

开发者 https://www.devze.com 2023-02-18 08:24 出处:网络
Platform: Rail 3.0 Database: mysql 5.1 Business requirement: Only one item of a product can be issued at a time. After a return of the issued item开发者_如何学C, a new item can be issued of same prod

Platform: Rail 3.0 Database: mysql 5.1

Business requirement: Only one item of a product can be issued at a time. After a return of the issued item开发者_如何学C, a new item can be issued of same product. Multiple items from different products can be issued at a time.

To implement the above business requirement, I am checking if there is already an item issued for the same product within the same date range (by checking to see if there is an overlap of the dates in my where below).

     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

Validation defined above works fine on create but in case of update i need to implement different logic. I do not want to define two methods for same requirement. so i want to implement checks with function based upon whether its update or create operation.Is there any way i can know if operation which triggered validate is update or delete?


Simple solution is to define a method to validate it, with a parameter, and then have two validations with different :on => calls, that in turn call the first method with a parameter.

Also, if it helps, you might use new_record? which will tell you if the object is being created (before it is saved)


Validations can be run at any time, not just within create, save, update_attributes, etc. So even if you could know what method triggered the validation (you can hack around with the output of caller), you should not make any use of it because it could be something completely valid yet completely unexpected.

However, all is not lost. You can check whether the record has been persisted yet by calling 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
0

精彩评论

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