如何通过协会来确定范围

时间:2015-11-22 01:18:23

标签: ruby-on-rails ruby postgresql activerecord scope

我在使用Rails 4和Postgres进行查询时遇到问题。

我有一个有很多选项的对象。

我想创建一个范围来根据选项ID数组选择对象。

类似的东西:

scope :with_options, -> (option_ids) { joins(:options).where('options.id IN (?)', option_ids) }

但我不需要 ANY ,我需要所有

EI。

如果我选择了带有[2,3,4]的选项,我想选择与所有这些选项ID相关的所有对象,而不仅仅是其中一些。

我尝试使用包含操作检查postgres_ext gem,但我无法使用关联。

这是我的结构:

class MyObject < ActiveRecord::Base
  has_many :my_object_options
  has_many :options, through: :my_object_options
end

class MyObjectOption < ActiveRecord::Base
  belongs_to :my_object
  belongs_to :option
end

class Option < ActiveRecord::Base
  has_many :my_object_options
  has_many :my_object, through: :my_object_options
end

关于如何构建我的范围的任何想法?

由于

修改

我写了一个快速测试,通过spickermann解决方案。

我在此粘贴测试说明。

describe "#with_options" do
  context "passing 2 options" do
    context "a my_object associated with both" do
      it "should be included"
    end

    context "a my_object associated only with one of the two options" do
      it "should not be included"
    end

    context "a my_object associated with one of the two options and a third one" do
      it "should not be included"
    end
  end
end

1 个答案:

答案 0 :(得分:1)

尝试计算相关选项的数量并返回具有最小匹配数的选项:

scope :with_options, lambda { |option_ids|   
  joins(:options).
  where(options: {id: option_ids }).
  group('my_objects.id').
  having('COUNT(DISTINCT options.id) >= ?', option_ids.size)
}