Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 具有多个ID的复杂数据库查询_Ruby On Rails_Ruby_Ruby On Rails 3_Ruby On Rails 3.2 - Fatal编程技术网

Ruby on rails 具有多个ID的复杂数据库查询

Ruby on rails 具有多个ID的复杂数据库查询,ruby-on-rails,ruby,ruby-on-rails-3,ruby-on-rails-3.2,Ruby On Rails,Ruby,Ruby On Rails 3,Ruby On Rails 3.2,我有3个模型,它们是这样连接的: class FooTemplate < ActiveRecord::Base has_many :foos end class Foo < ActiveRecord::Base belongs_to :foo_template belongs_to :bar end class Bar < ActiveRecord::Base has_many :foos end 该参数是一个数组,始终具有以下形式: ["

我有3个模型,它们是这样连接的:

class FooTemplate < ActiveRecord::Base
    has_many :foos
end

class Foo < ActiveRecord::Base
    belongs_to :foo_template
    belongs_to :bar
end

class Bar < ActiveRecord::Base
    has_many :foos
end
该参数是一个数组,始终具有以下形式:

[""]
["", "1", "2"]
即使未提交ID,数组也始终包含空字符串

我希望你明白我想做什么

更新

让我给你举个例子:

Bar: 1
  Foo: 1
    FooTemplate: 1
  Foo: 2
    FooTemplate: 2

Bar: 2
  Foo: 3
    FooTemplate: 2
  Foo: 4
    FooTemplate: 3

Bar: 3
  Foo: 5
    FooTemplate: 3
  Foo: 6
    FooTemplate: 4
这应为3根钢筋,每个钢筋具有2个独立的FOO。Foo有一些“重叠”的脚部模板

下面是一些列表的预期结果:

["1"] schould only return Bar 1, because it's the only one whose Foos have a FooTemplate 1.
["2"] should return Bar 1 & 2, because they both have a Foo with a FooTemplate 2
["2", "3"] should return only Bar 2, because it's the only one which has a Foo with FooTemplate 2 AND a Foo with FooTemplate 3
["1", "4"] should return nothing because there is no Bar whose Foos have FooTemplates 1 AND 4
更新2

我找到了一个可行的解决方案,但它使用reject并生成更多的数据库查询:

class Bar < ActiveRecord::Base
    has_many :foos
    has_many :foo_templates, through: :foos

    def self.find_by_foo_template_ids(foo_template_ids)
        ids = foo_template_ids.map { |id| id.to_i }

        joins(foos: :foo_template).uniq.where(foos: { foo_template_id: ids }).reject do |bar|
            !(bar.foo_template_ids & ids == ids)
        end
    end
end
类栏

这将返回一个数组,但我希望有一个
ActiveRecord::Relation
来对其执行额外的查询。

N.B.这几乎肯定只是PostGres。这也感觉有点像黑客。但我认为它会起作用

def self.find_by_foo_templates(foo_template_ids)
  joins(:foos => :foo_template).where(['foo_templates.id in (?)', foo_template_ids.reject!(&:empty?)])
end
def self.find_by_foo_templates(foo_template_ids)
  joins(:foos => :foo_template).
  group('bars.id').
  having("array_agg(foo_templates.id) @> string_to_array(?, ',')::int[]", foo_template_ids.join(','))
end

这应该聚合与每个返回条关联的foo一起使用的FooTemplates的id,并且只返回包含所有输入id的条

这将返回多个条。我只希望一个条出现一次,并且返回的属于该条的foo必须属于列表中的所有FooTemplates。PostgreSQL从何而来?OP没有提到使用它。我现在正在使用SQLite 3。@theTinMan it也没有提到不使用PostGresSQL(好吧,直到现在),而且它在Rails世界中非常常见,所以我想我应该提供我知道的解决方案。我不知道如何在SQLite中做到这一点,但它至少可以帮助其他人解决类似的问题。
def self.find_by_foo_templates(foo_template_ids)
  joins(:foos => :foo_template).
  group('bars.id').
  having("array_agg(foo_templates.id) @> string_to_array(?, ',')::int[]", foo_template_ids.join(','))
end