【问题标题】:Rails: better way to check for associated object by nameRails:通过名称检查关联对象的更好方法
【发布时间】:2013-09-20 21:18:18
【问题描述】:

我的产品模型中有以下方法:

def has_feature? (feature_name)
  self.features.where(:name=>feature_name).present?
end

这似乎很慢。有没有更好的方法来检查我的产品是否具有给定名称的功能?

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    .present? 不是ActiveRecord::Relation 上的标准方法,这是where 返回的。调用.present? 是获取具有给定名称的所有特征,更改为一个数组,然后在该数组上调用.present?

    如果您改为调用.exists?,则执行的数据库查询会稍微优化以检查该功能是否存在。

    但是,我不确定您是否会注意到这两个选项之间的性能差异。最可能的原因是您缺少数据库索引。假设您的关联是Product has_many :features,那么将通过features.product_idfeatures.name 上的索引来改进将生成的数据库查询。

    【讨论】:

    • 您会建议添加索引并调用 .exists 吗?或按照 Raghu 的建议添加索引并使用范围
    • 我建议添加一个包含两个字段的索引,然后从那里使用您觉得最舒服的方法。
    • 好吧,我都可以接受,我只是说......从速度的角度来看,什么是最好的......我会从你的回答中假设这并不重要。
    • 抱歉,我的暗示太隐晦了,添加索引后两种方法之间不会有任何明显的区别。
    • 没问题。如果您愿意,我还有一个相关的问题stackoverflow.com/questions/18926627/…
    【解决方案2】:

    另一种编写方式是在您的 Feature 模型中使用范围,看看它是否有帮助,并在该范围的结果输出上执行 present?

    scope :includes_feature, lambda{ |feature|
      { :name => feature }
    }
    

    所以最后你可以做的是product.features.includes_feature(feature_name)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-20
      相关资源
      最近更新 更多