2009-10-02 14 views
65

Bu kodu vardırRails ActiveRecord: INNER JOIN yerine SOL JOIN ile birleşir

User.find(:all, :limit => 10, :joins => :user_points, 
       :select => "users.*, count(user_points.id)", :group => 
       "user_points.user_id") 

hangi üretir aşağıdaki sql

SELECT users.*, count(user_points.id) 
FROM `users` 
INNER JOIN `user_points` 
ON user_points.user_id = users.id 
GROUP BY user_points.user_id 
LIMIT 10 

o sol birleştirme yapmak yerine INNER User.find_by_sql dışındaki yol KATILIN ve sorgu yazarak manuel mümkün mü?

cevap

82

Sen :all kaldırılmış mesajı verir ekleyerek, sadece ileride başvurmak üzere bu

User.find(:all, limit: 10, 
      joins: "LEFT JOIN `user_points` ON user_points.user_id = users.id" , 
      select: "users.*, count(user_points.id)", 
      group: "user_points.user_id") 
+0

harika, ben –

+0

arıyordu tam olarak ne Tamam, ama Jakub gerçekten ne bekliyoruz ki? Puansız kullanıcılar? Eğer öyleyse, bence 'WHERE user_points.user_id IS NULL', hayır? –

+0

@Kylo, ​​bir dizeye yazmadan sol birleştirmeyi oluşturmak için raylarda bir yapı var mı? – BKSpurgeon

36

deneyebilirsiniz.

User.joins("LEFT JOIN `user_points` ON user_points.user_id = users.id").select("users.*, count(user_points.id)").group("user_points.user_id") 

VEYA böyle bir kapsamı kullanın:: Rayların sonraki sürümlerinde böyle yöntemler sadece zincir olabilir

scope :my_scope_name_here, -> { 
     joins("LEFT JOIN `user_points` ON user_points.user_id = users.id") 
     .select("users.*, count(user_points.id)") 
     .group("user_points.user_id") 
} 

Ayrıca .join ve .select arasında .where zincirlemek olabilir. Umut, bu gelecekte birilerine yardımcı olur.

2

Raylar 5, left_outer_joins yöntemine sahiptir. Yani takma adını

User.left_outer_joins(:user_points) 

yapmak ya kullanabilirsiniz

User.left_joins(:user_points)