如何使用rails 3搜索多个到多个表

时间:2013-01-23 12:01:17

标签: sql ruby-on-rails search many-to-many

我有三个表格,其中包含模具(模具)的详细信息,以及通过流派表格链接在一起的模式:

Mould table
id : integer
name : string


Pattern table
id : integer
name : string

genres table
id : integer
mould_id :integer
pattern_id : integer

表格中有数据如下

Mould table
ID          Name
1           A1
2           A2
3           A3
53          A4
54          A5
197         A6
198         A7
1204        A8
1205        A9

Pattern Table

ID         Name
1          Running
2          Scroll

Genres Table

ID     mould_id  pattern_id
1       1           1
2       2           1
3       3           1
4       53          1
5       53          2
6       54          1
7       197         2
8       198         1
9       1204        2
10      1205        1

从我的计算中,模具53,197和1204都有一个Scroll模式,所以我应该能够编写以下SQL来提供

SELECT m.id   FROM moulds m INNER JOIN genres g
ON m.id = g.mould_id INNER JOIN patterns p
ON g.pattern_id = p.id  
WHERE p.id = 2     
GROUP BY m.id    
HAVING COUNT(*) >= 1

但它只返回197所以那里有些错误(或者我的数据)

然后将它转换为Rails我将它包装在find_by_sql中,它给出相同的结果(这是有意义的)

有人可以帮助SQL或建议一种更好的rails方式来进行这种查询吗?

1 个答案:

答案 0 :(得分:1)

我已经测试了你上面的模型和数据,我得到了你期望的结果(即三个模具名称" A4"," A6"和& #34; A8&#34)。所以我怀疑你的数据正在发生。

除此之外,我建议使用Rails query methods来获取所需的数据,而不是诉诸SQL。例如,这个:

Mould.select('moulds.id')\
     .joins(:patterns)\
     .where('patterns.id' => 2)\
     .group('moulds.id')\
     .having('COUNT(*) >= ?', 1)

将生成此SQL:

SELECT moulds.id FROM "moulds"
INNER JOIN "genres" ON "genres"."mould_id" = "moulds"."id"
INNER JOIN "patterns" ON "patterns"."id" = "genres"."pattern_id"
WHERE "patterns"."id" = 2
GROUP BY moulds.id
HAVING COUNT(*) >= 1

这与您拥有的SQL几乎相同,并产生相同的结果(同样,正确的结果有三个结果)。

请注意,SQL的INNER JOIN genres g部分在此处没有明确提及。只要您在throughMould上定义了Pattern个关联,就可以使用此功能:

class Mould < ActiveRecord::Base
  has_many :genres
  has_many :patterns, :through => :genres
  #...
end

class Pattern < ActiveRecord::Base
  has_many :genres
  has_many :moulds, :through => :genres
  #...
end

由于您告诉Rails MouldPattern通过genres表关联,因此它知道如何构建正确的SQL查询以将它们连接在一起。

希望有所帮助。