2017-03-07 30 views
3

我想查詢private_classes的結果。情景是:如何在Ruby on Rails中使用包含或連接來獲取其他表的結果

class PrivateClass < ActiveRecord::Base 
    belongs_to :private_school 
    has_many :lesson_plans 
end 

class JoinedPrivateSchool < ActiveRecord::Base 
    belongs_to :student 
    belongs_to :private_school 
end 

class PrivateSchool < ActiveRecord::Base 
    belongs_to :teacher 
    has_many :private_classes 
    has_many :joined_private_schools 
end 

class Student < ActiveRecord::Base 
    has_many :joined_private_schools 
end 

JoinPrivateSchool具有屬性private_school_id

我做:

s = Student.find(9) 

s.joined_private_schools 

導致:

=> #<ActiveRecord::Associations::CollectionProxy [#<JoinedPrivateSchool id: 8, 
user_id: 73, student_id: 9, private_school_id: 28, created_at: "2017-02-16 
12:38:37", updated_at: "2017-02-16 12:38:37">, #<JoinedPrivateSchool id: 9, 
user_id: 73, student_id: 9, private_school_id: 33, created_at: "2017-02-16 
12:42:01", updated_at: "2017-02-16 12:42:01">, #<JoinedPrivateSchool id: 12, 
user_id: 73, student_id: 9, private_school_id: 32, created_at: "2017-02-16 
13:19:02", updated_at: "2017-02-16 13:19:02">]> 

如果我做的:

c = s.joined_private_schools.includes(private_school: :private_classes) 

它導致:

JoinedPrivateSchool Load (0.6ms) SELECT "joined_private_schools".* FROM 
"joined_private_schools" WHERE "joined_private_schools"."student_id" = $1 
[["student_id", 9]] 


PrivateSchool Load (0.9ms) SELECT "private_schools".* FROM "private_schools" 
WHERE "private_schools"."id" IN (28, 33, 32) ORDER BY 
"private_schools"."created_at" DESC 


PrivateClass Load (0.7ms) SELECT "private_classes".* FROM "private_classes" 
WHERE "private_classes"."private_school_id" IN (33, 32, 28) ORDER BY 
"private_classes"."created_at" DESC 


=> #<ActiveRecord::AssociationRelation [#<JoinedPrivateSchool id: 8, user_id: 
73, student_id: 9, private_school_id: 28, created_at: "2017-02-16 12:38:37", 
updated_at: "2017-02-16 12:38:37">, #<JoinedPrivateSchool id: 9, user_id: 73, 
student_id: 9, private_school_id: 33, created_at: "2017-02-16 12:42:01", 
updated_at: "2017-02-16 12:42:01">, #<JoinedPrivateSchool id: 12, user_id: 73, 
student_id: 9, private_school_id: 32, created_at: "2017-02-16 13:19:02", 
updated_at: "2017-02-16 13:19:02">]> 

但那仍然是錯誤的結果。

我需要使用一個查詢來獲得private_classes的結果,這樣我就可以避免多個每個循環。

+0

我建議你看看這篇文章(http://blog.bigbinary.com/2013/07/01/preload-vs-eager-load-vs-joins-vs-includes .html)來理解'includes'(和'joins','eager_load'和'preload')的作用。 – lcguida

回答

2

如果您想擁有PrivateClass,那麼您從錯誤的角度出發(User)。你需要從PrivateClass開始參加所有的中介表,並使用用戶ID作爲條件:

PrivateClass.joins(private_school: :user).where(user: {id: 9}) 

# or a little more performant (avoids one join) 

PrivateClass.joins(:private_school).where(private_school: {user_id: 9}) 
2

您可以在協會使用:through(至少在Rails的4.2)
我更新了這個,我第一次錯過了你想private_classes

class JoinedPrivateSchool < ActiveRecord::Base 
    belongs_to :student 
    belongs_to :private_school 
    has_many :private_classes, through: :private_schools 
end 

class Student < ActiveRecord::Base 
    has_many :joined_private_schools 
    has_many :private_classes, through: :joined_private_schools 
end 

s = Student.find(9) 
s.private_classes 
相關問題