如何在父对象中记忆昂贵的查询并在子对象中重用它?我面临的问题是,每次我从子到父:child1.parent或child2.parent进行引用时,它会给出不同的对象id,并且不会发生memoization。
class Post
has_many :comments
def total_comments
unless @total_comments
puts "Loading comments"
@total_comments = comments.count
end
@total_comments
end
end
class Comment
belongs_to :post
def total_comments
post.total_comments
end
end
post.comments[0].total_comments
post.comments[1].total_comments
这应该只查询一次评论,但因为它没有记录在同一个对象上,所以它加载了两次
Loading comments...
Loading comments...
答案 0 :(得分:1)
尝试此帖子= Post.last(include: :comments)
此语句急切加载关系现在执行操作post.comments[0]
这不会触发任何SQL
查询,因为相关记录已经存在
答案 1 :(得分:1)
<强> 1。使用ActiveRecord Association Extensions
class Post
has_many :comments do
def total
proxy_association.target.size
end
end
end
允许您调用proxy_association
对象,并将该方法附加到comments
的实例(以便您可以调用@post.comments.total
)
<强> 2。使用:inverse_of
#app/models/post.rb
Class Post < ActiveRecord::Base
has_many :comments, inverse_of: :post
end
#app/models/comment.rb
Class Comment < ActiveRecord::Base
belongs_to :post, inverse_of: :comments
end
允许您从self
(self.post.total_comments
)
第3。使用“Eager Loading”(将对象保留在内存中)
这是查询级别,并且在NitinJ的答案中提到了&amp; this RailsCast:
Post.includes(:comments)
我认为NitinJ的评论比我的好,因为我只有使用.includes
创建数据库调用的经验(不在关联容量中使用它)
奖励 - Counter-Cache - 使用此代替comments.count
- 它将计数存储在内存中,这将删除昂贵的数据库调用!