我可以使用符合特定条件的多个关联记录查询记录吗?

Joe*_*ano 17 ruby mysql sql ruby-on-rails

我有两张桌子Show,Character.每个Show has_many Characters.

class Show < ActiveRecord::Base
  has_many :characters

class Character < ActiveRecord::Base
  belongs_to :show
Run Code Online (Sandbox Code Playgroud)

我想要做的是返回与符合特定条件的多个字符相关联的Show的结果.

例如,我希望能够返回一个包含蝙蝠侠和罗宾字符的节目列表.不是蝙蝠侠或罗宾,蝙蝠侠和罗宾.

所以查询应该是这样的

Show.includes(:characters).where(characters: {'name = ? AND name = ?', "Batman", "Robin"})
Run Code Online (Sandbox Code Playgroud)

但这会返回错误.是否有一个可行的语法?

UPDATE

查询

Show.includes(:characters).where('characters.name = ? AND characters.name = ?', "Batman", "Robin")
Run Code Online (Sandbox Code Playgroud)

返回值0,即使有明确的显示与蝙蝠侠和罗宾相关联.

Ren*_*ern 11

使用纯SQL,一个解决方案是:

select s. * 
from shows as s 
join characters as c1 on (s.id=c1.show_id) 
join characters as c2 on (s.id=c2.show_id) 
where c1.name='Batman' 
and   c2.name='Robin';
Run Code Online (Sandbox Code Playgroud)

使用Arel,我会翻译为:

Show.joins('join characters as c1 on shows.id=c1.show_id').joins('join
characters as c2 on shows.id=c2.show_id').where('c1.name = "Batman"').where(
'c2.name="Robin"')
Run Code Online (Sandbox Code Playgroud)


Jam*_*els 6

所以你必须在这里看一点SQL; 特别是如果你希望它具有高性能并处理不同类型的匹配器.

select count(distinct(characters.name)) as matching_characters_count, shows.* from shows
  inner join characters on characters.show_id = shows.id and (characters.name = 'Batman' or characters.name = 'Robin')
group by shows.id
having matching_characters_count = 2
Run Code Online (Sandbox Code Playgroud)

要翻译成ActiveRecord

Show.select('count(distinct(characters.name)) as matching_characters_count, shows.*').
   joins('inner join characters on characters.show_id = shows.id and (characters.name = "Batman" or characters.name = "Robin")').
   group('shows.id').
   having('matching_characters_count = 2')
Run Code Online (Sandbox Code Playgroud)

然后你可能会进行插值传递,然后AREL它; 所以你不会构建字符串查询.