Rails 快速查找 has_many 关联与关联 ID 数组完全匹配的记录
Rails quickly find record where has_many associations exactly match array of association ids
我有一个 Product
模型,其中 has_many
OptionValue
记录了描述 color
、size
等
在我的代码中,我需要查询 product.option_values.pluck(:id)
数组与(例如)options = [1, 6, 4]
数组完全匹配的产品模型。
运行 类似于 Product.includes(:option_values).where(option_values: { id: options_array })
returns 匹配选项数组中至少一个元素的所有值,而不是所有值。
我开发了一种获取所需记录的低效方法,如下所示:
Product.all.each { |v| return v if v.option_values.pluck(:id).sort == options_array.sort }
显然上面的方法很简单,我相信有更简单的方法来处理这个问题,我很乐意使用 ActiveRecord 或直接 SQL 查询(虽然我不太热衷于后者,所以还没有想出任何办法。
非常感谢任何有关实现此目标的最佳方法的建议。不确定我是否已经完美地解释了这一点,所以如果您有任何问题,请发表评论。
提前致谢,史蒂夫。
在我的老问题中解决了这个问题并拼凑了一个快速简单的解决方案,所以把它放在这里以供可能以这种方式出现的任何其他人使用:
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 & options_array)
)
- 测量它们的长度
- 检查这是否与所需数组的长度相同
product_options
,这意味着已找到所有必需的选项。
或者,您可以从另一个中减去一个并检查是否有剩余(即丢失):
(product_options - options_array).empty?
希望这对某些人有所帮助。
我有一个 Product
模型,其中 has_many
OptionValue
记录了描述 color
、size
等
在我的代码中,我需要查询 product.option_values.pluck(:id)
数组与(例如)options = [1, 6, 4]
数组完全匹配的产品模型。
运行 类似于 Product.includes(:option_values).where(option_values: { id: options_array })
returns 匹配选项数组中至少一个元素的所有值,而不是所有值。
我开发了一种获取所需记录的低效方法,如下所示:
Product.all.each { |v| return v if v.option_values.pluck(:id).sort == options_array.sort }
显然上面的方法很简单,我相信有更简单的方法来处理这个问题,我很乐意使用 ActiveRecord 或直接 SQL 查询(虽然我不太热衷于后者,所以还没有想出任何办法。
非常感谢任何有关实现此目标的最佳方法的建议。不确定我是否已经完美地解释了这一点,所以如果您有任何问题,请发表评论。
提前致谢,史蒂夫。
在我的老问题中解决了这个问题并拼凑了一个快速简单的解决方案,所以把它放在这里以供可能以这种方式出现的任何其他人使用:
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 & options_array)
) - 测量它们的长度
- 检查这是否与所需数组的长度相同
product_options
,这意味着已找到所有必需的选项。
或者,您可以从另一个中减去一个并检查是否有剩余(即丢失):
(product_options - options_array).empty?
希望这对某些人有所帮助。