0

我有以下型号:

供应商有许多提交的价格

Submitted_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,恕我直言,这是一种代码味道。

如果您仍然想要,那么您需要在第一次尝试后在每次通话中使用它。

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)

我建议您将大量此类逻辑提取到单独的范围和方法中,该语句中发生的事情太多了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 回答