1

プラットフォーム: Rail 3.0 データベース: mysql 5.1

ビジネス要件: 一度に発行できる商品は 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 つのメソッドを定義したくありません。そのため、更新または作成操作に基づいて関数でチェックを実装したいと考えています。検証をトリガーした操作が更新または削除であるかどうかを知る方法はありますか?

4

2 に答える 2

2

簡単な解決策は、パラメーターを使用してそれを検証するメソッドを定義し、次に異なる:on =>呼び出しで2つの検証を行い、次にパラメーターを使用して最初のメソッドを呼び出すことです。

また、役立つnew_record?場合は、オブジェクトが作成されているかどうか(保存される前)を通知するを使用できます。

于 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 に答える