2014-04-16 23 views
7

Tek bir sql sorgusunda Yorumlarsız Kullanıcılar'ı sorgulamak istermiyim?Rails User.joins.not (...) Aktif Kayıtta mı?

Modeller:

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

Ama bu gibi: (Bu iki sorgu oluşturur çünkü)

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

Belki bir şey gibi

class User < ActiveRecord::Base 
    has_many :comments 
end 

class Comment < ActiveRecord::Base 
    belongs_to :user 
end 

Yani bunun tersini istiyorum bu?

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

Herhangi bir girdi için teşekkürler! Tek bir (gerçi iç içe) sorgu isteseydim

+0

deneyin 'User.includes (: yorum) .Where (yorumlar: {id: nil})' – MrYoshiji

cevap

11

Sen

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

gibi bir şey yapabilirsiniz.

Aksi takdirde, bir dış birleştirmeyi kullanmak için http://guides.rubyonrails.org/active_record_querying.html#joining-tables'a bakın.

+1

o alt sorgu veya 2 farklı sorguları kullanacak mı? – thethanghn

+2

@thethanghn bu durumda bir alt sorgu ile sonuçlanacaktır. Bir "ActiveRecord :: Relation" (herhangi bir sorgu yöntemine "select" ve "where" gibi aktif kayıt sorgulama yöntemleri) ne olursa olsun, bir alt sorgu sonuçlanır. –

2

Eğer bu bu sorguyu

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 

Bu sorgu (iç içe sql ne) iki SQL oluşturmayan üretecektir bu

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

gibi bir şey yapabilirsiniz postgresql kullanıyorsanız, yukarıdaki cevabı yapar.

+0

Bu sorgudaki 'c' ve' u ne anlama geliyor? – thiebo

+1

@thiebo "c", yorumlar tablosu için bir takma addır ve "u" kullanıcı tablosu için bir takma addır. SQL takma adları hakkında daha fazla bilgiyi burada bulabilirsiniz (https://en.wikipedia.org/wiki/Alias_ (SQL)) –

0

Başka basit bir çözüm User.where("id NOT IN (?)", Comment.pluck(:user_id))