2013-03-15 1 views
1

Я пытаюсь вернуть записи из A, где все соответствующие записи из B удовлетворяют условию. В настоящий момент мой запрос возвращает записи из A, где есть какая-либо запись из B, которая удовлетворяет условию. Позвольте мне привести это в сценарий реального мира.Условие true для ВСЕХ записей в соединении

Post.joins(:categories) 
    .where(:categories => { :type => "foo" }) 

Это вернет Post S, которые имеют категорию типа «Foo», что я хочу Post s, чьи категории ВСЕ типа «Foo»!

Помогите оценить!

+0

Ваш запрос должен работать нормально. что вы подразумеваете под ** ALL типа «foo»! **. – shweta

+0

Ну, он возвращает сообщения, которые имеют любые категории типа foo. Если сообщение имеет 5 категорий, и они не все типа foo, я не хочу, чтобы он возвращал их. –

ответ

2

Использование дб/schema.rb, как писал в #rubyonrails на IRC-то вроде:

Incident.select("incidents.id"). 
joins("INNER JOIN category_incidents ON category_incidents.incident_id = incidents.id"). 
joins("INNER JOIN category_marks ON category_marks.category_id = category_incidents.category_id"). 
where(:category_marks => { :user_group_id => current_user.user_group_id }). 
group("incidents.id"). 
having("SUM(CASE WHEN category_marks.inc = 1 THEN 1 ELSE 0 END) = count(category_indicents.incident_id)") 

будет делать трюк.

Он присоединяется к category_marks для current_user и проверяет, соответствует ли количество записей с .inc = 1 числом всех объединенных записей.

Обратите внимание, что это происходит только из-за инцидента.

+1

Приятный! Muchas gracias, как говорят в Испании .. возможно. –

1

Я бы добавил в конце этого запроса, чтобы проверить, есть ли у всех категорий тип foo. Я бы также упростил эту проверку, добавив метод экземпляра в модель категории.

Post.joins(:categories).select{|p| p.categories.all?(&:type_foo?)} 

Категория Модель

def type_foo? 
    type == "foo" 
end 

Сложение: Это немного "Hacky", но вы можете сделать это таким образом, сфера применения.

class Post < ActiveRecord::Base 
    scope :category_type_foo, lambda{ 
    post_ids = Post.all.collect{|p| p.id if p.categories.all?(&:type_foo?).compact 
    Post.where(id: post_ids) } 
end 
+0

Это было бы здорово, но мне нужно вернуть область действия/отношения! :( –

0

Вы пробовали запрос в обратном направлении? то есть

Categories.where(type: 'foo').joins(:posts) 

Возможно, я неправильно понял ваш вопрос.

Другой альтернативой является

Post.joins(:classifications).where(type: 'foo') 
+0

Запрос в обратном направлении по-прежнему будет возвращать любое сообщение с категорией с типом foo, не обязательно сообщениями со всеми категориями типа foo. –