0

我在我的模型中定义了一个非常复杂的方法,我认为它是:

  def self.current_rating(recommendation_id, rating_set, product_id)
    if !Recommendation.find(recommendation_id).ratings.find_by_rating_set(rating_set).nil?
      Recommendation.find(recommendation_id).ratings.find_by_rating_set(rating_set).rating.to_i
    elsif  !Recommendation.find(recommendation_id).ratings.find_by_product_id(product_id).nil?
      Recommendation.find(recommendation_id).ratings.find_by_product_id(product_id).rating.to_i
    else
    end
  end

在我看来,我打电话给:

:selected => Rating.current_rating(rec.id,params[:rating_set_id], params[:product_id])

在我的select_tag.

基本上我想检查第一次查找是否返回任何内容,是否nil检查第二次查找,如果nil没有返回任何内容。我如何将其重构为更好/更具语法性?

4

2 回答 2

0
def self.current_rating(recommendation_id, rating_set, product_id)
    r = Recommendation.find(recommendation_id).ratings
    x = r.find_by_rating_set(rating_set) || r.find_by_product_id(product_id)
    x && x.rating.to_i
end

所以我注意到你所有的表达都是从根据 reco id 找到推荐并获得它的评级开始的。所以我先这样做,分配给r.

然后我尝试通过 rating_set 查找,如果失败(它将返回 nil)它会短路到通过产品 id 查找。如果失败(nil),那么 x 将为 nil。

无论我们是通过 rating_set 还是 product id 来查找,都有一个 rating 方法。所以如果 x 不是 nil (x &&) 我们调用 rating,然后调用 to_i。它被返回,因为它是最后一个表达式。

如果 x 为 nil,则返回 (nil && whatever) 的结果,即 nil。

于 2013-03-19T04:12:29.623 回答
0

你可以做各种各样的事情。在不了解您的应用程序的情况下,以下是我的建议:

其中的每一步都包括Recommendation.find(recommendation_id),这让我认为您希望这是Recommendation模型上的一个实例方法,因此您可能不会运行 4 个相同的推荐查找。

此方法的第一行从推荐中获取您想要的评级。除非找到某些东西,否则该rating变量将保留。nil

def current_rating(rating_set, product_id)
  ratings.find_by_rating_set(rating_set) || ratings.find_by_product_id(product_id)
end

所以现在你只剩下一个返回 arating或的方法nil。由于我们不知道您打算对此做什么,因此很难说您下一步应该做什么,但我认为这是针对这种情况的更好的总体策略,因为这种方法的意图很明确,至少在某种程度上它的输出是可预测的(如果我调用一个current_rating方法并收到一个整数而不是一个 Rating 对象,我会有点惊慌)。如果使用它在视图中显示评级的数字,这是装饰器或其他模式的良好候选者。

于 2013-03-19T04:22:50.117 回答