2014-04-16 13 views
7

Ich suche, alle Benutzer ohne Anmerkungen in einer einzelnen sql Abfrage abzufragen?Schienen Benutzer.joins.not (...) in Active Record?

Modelle:

class User < ActiveRecord::Base 
    has_many :comments 
end 

class Comment < ActiveRecord::Base 
    belongs_to :user 
end 

So möchte ich das Gegenteil davon:

User.joins.(:comments).group('users.id') 

Aber nicht dies mag:

User.where.not(id: Comment.pluck(:user_id)) 

Vielleicht wie etwas (weil es zwei Abfragen generiert) Dies?

User.joins.not.(:comments).group('users.id') 

Danke für jede Eingabe!

+0

Try 'User.includes (: Kommentare) .wo (Kommentare: {id: nil})' – MrYoshiji

Antwort

11

Sie können so etwas wie

User.where.not(id: Comment.select(:user_id)) 

tun Wenn Sie eine einzelne (obwohl verschachtelte) Abfrage wollen.

Andernfalls überprüfen Sie http://guides.rubyonrails.org/active_record_querying.html#joining-tables für die Verwendung einer äußeren Verknüpfung.

+1

es Unterabfrage oder 2 verschiedene Abfragen verwenden? – thethanghn

+2

@thethanghn in diesem Fall wird es zu einer Unterabfrage führen. Jedes Mal, wenn Sie eine 'ActiveRecord :: Relation' übergeben (was ist, was die aktiven Datensatzabfragemethoden wie' select' und 'where' zurückgeben) zu einer Abfrage-Methode, wird eine Unterabfrage resultieren. –

2

Wenn Sie postgresql verwenden Sie so etwas wie dieses

User.joins("LEFT join comments c on users.id = c.comment_id"). 
select("users.id"). 
group("users.id"). 
having("count(users.id) = 1") 
tun können

Dies wird diese Abfrage generieren

select u.id from users u 
LEFT join comments c 
on c.comment_id = u.id 
group by u.id 
having count(u.id) = 1 

Diese Abfrage nicht erzeugt zwei SQL (weder verschachtelte SQL), die oben genannte Antwort tut.

+0

Wofür stehen 'c' und' u' in dieser Abfrage? – thiebo

+1

@thiebo "c" ist ein Alias ​​für die Kommentartabelle & "u" ist ein Alias ​​für die users-Tabelle. Mehr über SQL-Aliase [hier] (https://en.wikipedia.org/wiki/Alias_ (SQL)) –

0

Eine weitere einfache Lösung User.where("id NOT IN (?)", Comment.pluck(:user_id))