I want to query the results of private_classes. The scenario is:
我想查询private_classes的结果。的场景是:
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 has the attribute private_school_id
.
JoinPrivateSchool具有private_school_id属性。
I am doing:
我做的事情:
s = Student.find(9)
s.joined_private_schools
which results in:
结果:
=> #<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">]>
If I do:
如果我做的事:
c = s.joined_private_schools.includes(private_school: :private_classes)
it results in:
结果:
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">]>
But that is still the wrong results.
但这仍然是错误的结果。
I need to get the results of private_classes using one query so I can avoid multiple each loops.
我需要使用一个查询获取private_classes的结果,这样我就可以避免多个循环。
2 个解决方案
#1
2
If you want to have PrivateClass
, you're starting from the wrong point (User
). You need to start from PrivateClass
joining all the intermediary tables and using the user id as condition:
如果您想拥有PrivateClass,您是从错误的点(用户)开始的。您需要从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
2
You can use :through
on associations (at least in Rails 4.2)
I updated this, I first missed that you wanted private_classes
您可以使用:通过关联(至少在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
#1
2
If you want to have PrivateClass
, you're starting from the wrong point (User
). You need to start from PrivateClass
joining all the intermediary tables and using the user id as condition:
如果您想拥有PrivateClass,您是从错误的点(用户)开始的。您需要从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
2
You can use :through
on associations (at least in Rails 4.2)
I updated this, I first missed that you wanted private_classes
您可以使用:通过关联(至少在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