【问题标题】:Rails quickly find record where has_many associations exactly match array of association idsRails 快速找到 has_many 关联与关联 ID 数组完全匹配的记录
【发布时间】:2016-05-24 13:27:58
【问题描述】:

我有一个Product 模型,其中has_many OptionValue 记录,描述colorsize 等。

在我的代码中,我需要查询 product.option_values.pluck(:id) 数组与(例如)options = [1, 6, 4] 数组完全匹配的 Product 模型。

运行Product.includes(:option_values).where(option_values: { id: options_array }) 之类的操作会返回与选项数组中至少一个元素匹配的所有值,而不是所有值。

我开发了一种获取所需记录的低效方法,如下所示:

Product.all.each { |v| return v if v.option_values.pluck(:id).sort == options_array.sort }

显然,上述方法很糟糕,我确信有一种更简单的方法来处理这个问题,我很高兴使用 ActiveRecord 或直接 SQL 查询(尽管我对后者不太感兴趣,所以没有'还没想出什么)。

任何关于实现这一目标的最佳方式的建议都非常感谢。不确定我是否已经完美地解释了这一点,所以如果您有任何问题,请发表评论。

在此先感谢史蒂夫。

【问题讨论】:

  • 如果产品有选项 [1,4,6,9] 并且您的搜索条件是 [1,4,6],会发生什么?是否匹配(因为该产品包含您搜索的所有条件)?还是不匹配(因为该产品至少有一个您没有搜索过的 OptionValue)
  • @MatBailie - 感谢您的快速回复。我正在查看 exact 匹配项,因此该方案不应返回产品。
  • 我不知道 RubyOnRails 表示法,但 SQL 是直截了当的 SELECT o.product_id FROM OptionValue o WHERE o.option_id IN (1,4,6) GROUP BY o.product_id HAVING COUNT(*) = 3
  • @SRack 我需要类似的东西。您找到的解决方案是什么

标签: mysql sql ruby-on-rails activerecord where-clause


【解决方案1】:

在我的旧问题中对此进行了计时,并提出了一个快速简便的解决方案,因此将其放在这里以供其他可能出现这种情况的人使用:

product_options = product.option_values.pluck(:id)
unless options_array.length < product_options.length
  (product_options & options_array).length == product_options.length
end

这个:

  • 检查options_array 是否足够长以包含必要的匹配项
  • 在两个数组中寻找共同的元素 ((product_options &amp; options_array))
  • 测量它们的长度
  • 检查这是否与所需数组product_options 的长度相同,这意味着找到了所有必需的选项。

或者,您可以从另一个中减去一个并检查是否有剩余(即丢失):

(product_options - options_array).empty?

希望这可以在某个时候帮助某人。

【讨论】:

    猜你喜欢
    • 2013-09-24
    • 1970-01-01
    • 2011-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-04
    • 2012-07-29
    相关资源
    最近更新 更多