我已经简化了我的项目,所以我可以理解RoR 3.2.13的热切加载部分。这些是我的课程:
class Person < ActiveRecord::Base
attr_accessible :name
has_many :posts
end
和
class Post < ActiveRecord::Base
attr_accessible :name, :person_id
belongs_to :person
end
当我做
之类的事情people_data = Person.includes(:posts)
IRB显示以下SQL:
Person Load (1.3ms) SELECT `people`.* FROM `people`
Post Load (0.7ms) SELECT `posts`.* FROM `posts` WHERE `posts`.`person_id` IN (1, 2)
结果对象如下:
=> [#<Person id: 1, name: "Ernie">, #<Person id: 2, name: "Bert">]
请注意,只有2个人对象,没有帖子。如何通过人员及其帖子获得简单的数据结构。我想在一条指令中做到这一点,我不想在人员阵列中做一个foreach。
我期待这样的事情:
[#<Person id: 1, name: "Ernie">, [#<Array 0 => #<Post id:1, name: "Hi">, 1 => #<Post id:2, name: "Hello"> > ....
答案 0 :(得分:3)
Eager loading 正在运作。它正在急切地检索所有帖子(在一个查询中)。急切加载不构建包含所有帖子和人员的数组。
# With eager loading
people_data = Person.includes(:posts) # 2 queries: 1 for persons, 1 for posts
people_data.first.posts.each do |post|
# No queries
end
# Without eager loading
people_data = Person.all # 1 query for persons
people_data.first.posts.each do |post|
# Query for each post
end
请注意,在这两种情况下,people_data
都将包含(看起来类似的)ActiveRecord::Relation
对象。 (它不是数组!)当您开始使用相关记录时,您只会看到热切加载的好处。
除非你有特殊的理由想要建立一个包含所有人和帖子的数组,否则你应该像使用它一样使用预先加载。这比尝试构建自己的数组更有效。
答案 1 :(得分:1)
您的查询结果急切地加载帖子作为Person#posts
方法的结果。我不太清楚你期望的输出格式。如果你只想要两个人,一个人和一个人,你可以把它分成两个查询。
@people = Person.where(...)
@posts = Post.where(person_id: @people)
这是通过急切加载完成的相同查询,但它将返回自己数组中的帖子。
答案 2 :(得分:1)
您可以将结果映射到接收预期的数组
Person.includes(:posts).all.map{|person| [person, person.posts]}