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)
所以你必须在这里看一点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它; 所以你不会构建字符串查询.