0

私は次のモデルを持っています:

サプライヤーには多くのsubmited_pricesがあります

Submitted_pricesには多くのprice_itemsがあります

submit_pricesやprice_itemsがない場合にコードがクラッシュしないようにするために、私は以下を使用していました。

 if supplier.submitted_prices.where(:purchaser_id => organization.id).last
 && supplier.submitted_prices.where(:purchaser_id => organization.id).last.price_items.where("item_id" => item.id).last
 && supplier.submitted_prices.where(:purchaser_id => organization.id).last.price_items.where("item_id" => item.id).last.unit_price.present?
  order_item.unit_price = supplier.submitted_prices.where(:purchaser_id => organization.id).last.price_items.where("item_id" => item.id).last.unit_price 

それから私はtry()に出くわしました:

order_item.unit_price = supplier.try(:submitted_prices).where(:purchaser_id => organization.id).try(:last).try(:price_items).where("item_id" => item.id).try(:last).try(:unit_price)

問題は、WHERE制約でtry()を実行する方法がわからないことです。この制約は、tryがnilを返すと失敗します。

NoMethodError Exception: undefined method `where' for nil:NilClass

try()をWHERE制約にラップする方法はありますか?

4

4 に答える 4

7

tryまず、 IMHOは使用しないでください。コードの臭いです。

それでも使用したい場合は、最初の試行後のすべての呼び出しでそれを使用する必要があります。

supplier.try(:submitted_prices).try(:where, {purchaser_id: organization.id}).try(:last).try(:price_items).try(:where, {item_id: item.id}).try(:last).try(:unit_price)

これは確かにいくつかの悪いデザインを示しています。最初にリファクタリングしてみてください!

于 2013-01-14T00:54:03.860 に答える
4

try後続のパラメータとして引数を受け入れます。次に例を示します。

try(:where, :purchaser_id => organization.id)

このロジックの多くを別々のスコープとメソッドに抽出することをお勧めします。その1つのifステートメントで発生することが多すぎて、オブジェクトグラフの奥深くまで到達しすぎています。デメテルの法則/最小知識の原則について読みたいと思うかもしれません。

于 2013-01-14T00:54:52.053 に答える
3

これは、なしtryで、より論理的で理解しやすい形式で実行できます。

submitted_price = supplier.submitted_prices.where(purchaser_id: organization.id).order("created_at desc").first
price_item      = submitted_price.price_items.where(item_id: item.id).order("created_at desc").first if submitted_price.present?

order_item.unit_price = price_item.unit_price if price_item.present?

これは、属性によるモデルのデフォルトの順序を前提としてい:createdます。

于 2013-01-14T01:01:38.270 に答える
1

ドキュメントを読むことで、このような複雑さを取り除くことができると思います。
(また、ブール句のチェーンを別の行で壊した場合は素晴らしいでしょう。私はあなたがそこで何をしようとしているのか理解するのが本当に難しいと感じています)

association.empty?おそらくメソッドとをチェックする必要がありassociation.exists?(conditions)ます。リンク

于 2013-01-14T01:02:01.277 に答える