【问题标题】:Is there any good way to DRY up scope / predicate logic duplication?有没有什么好的方法来干燥范围/谓词逻辑重复?
【发布时间】:2012-02-24 15:29:03
【问题描述】:

例如,考虑以下代码(在模型中):

scope :popular, where("views >= 250 OR (views >= 10 AND avg_rating >= 4.75)")

def popular?
  views >= 250 or views >= 10 && avg_rating >= 4.75
end

第一个条件是 SQL,第二个条件是 ruby​​,但仍然存在明显的重复。有什么好的方法可以晒干吗?这种情况的最佳做法是什么?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 activerecord scope dry


    【解决方案1】:

    两者都有很好的理由,所以我可能会考虑这个(全部在模型中):

    VIEWS_QUALIFIER = 250
    RATING_VIEWS_QUALIFIER = 10
    RATING_QUALIFIER = 4.75
    
    scope :popular, where("views >= ? OR (views >= ? AND avg_rating >= ? ",
                    VIEWS_QUALIFIER, RATING_VIEWS_QUALIFIER, RATING_QUALIFIER)
    
    def popular?
      views >= VIEWS_QUALIFIER or 
      (views >= RATING_VIEWS_QUALIFIER && avg_rating >= RATING_QUALIFIER)
    end
    

    【讨论】:

      【解决方案2】:
      def popular?
        !!self.class.popular.includes? self
      end
      

      【讨论】:

      • 建议不要使用上述方法,因为这会加载所有流行记录,只是为了检查一项是否流行。也许self.class.popular.exists?(id) 可能有用
      • @ThongKuah 所有类似解决方案还有另一个问题 - 当对象处于“脏”状态并且 viewsavg_rating 已更改但未保存时,该方法可能会返回错误结果
      • 在 SO 中总是有学习的地方。 TY为cmets! :)
      • @Alexis 是的,我很快就意识到了:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多