我有一个用户,帖子和评论的应用程序。用户has_many帖子,帖子has_many评论和意见belongs_to用户和帖子。Rails寻找关联的效率
在我看来模板我遍历这样的评论让评论者的用户名:
User.find(comment.user_id).name
效率如何这一点,如果我这样做是为每个职位每个评论? 我可以想象,将注册表中的用户名存储在单独的行中可能会更快,但是重复数据似乎只是错误的。
我是不是偏执狂,是ActiveRecord做一些缓存魔术还是有更好的方式做这样的事情吗?
我有一个用户,帖子和评论的应用程序。用户has_many帖子,帖子has_many评论和意见belongs_to用户和帖子。Rails寻找关联的效率
在我看来模板我遍历这样的评论让评论者的用户名:
User.find(comment.user_id).name
效率如何这一点,如果我这样做是为每个职位每个评论? 我可以想象,将注册表中的用户名存储在单独的行中可能会更快,但是重复数据似乎只是错误的。
我是不是偏执狂,是ActiveRecord做一些缓存魔术还是有更好的方式做这样的事情吗?
您可以在初始查询预加载的用户。 鉴于用户和评论之间的关联设置,您可以通过关联访问用户。
让我们假设你有一个控制器方法:
def show
@posts = Post.limit(10).includes(:comments => :user)
end
在你看来,你遍历@comments
:
@posts.each do |post|
# show post stuff
post.comments.each do |comment|
comment.user.name
end
end
class Post < ActiveRecord::Base
has_many :comments
# ...
end
class Comment < ActiveRecord::Base
belongs_to :user
end
comments = @post.comments.includes(:user)
它将预装用户。
SQL看起来像:
SELECT * FROM `comments` WHERE `comments`.`post_id` = 42;
SELECT * FROM `users` WHERE `users`.`id` IN (1,2,3,4,5,6) # 1,2,3,4,5,6 - user_ids from comments
但后来我不得不提出另一个请求来获取帖子... – DeanAlexRainier
你的意思是你想加载与评论用户与用户的帖子的帖子? – cutalion
修订
如果您有关联作为下面你可以访问用户来自评论对象本身comment.user
class User < ActiveRecord::Base
has_many :posts
has_many :comments
end
class Post < ActiveRecord::Base
belongs_to :user
has_many :comments
end
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :post
end
如果性能对您而言是个问题,那么使用非关系型数据库(如Mongodb)是一条可行之路。
如果你仍然想使用ActiveRecord,无论您使用Post.comments.include(:user)
预先加载(这将加载未使用的用户信息 - 这不是很大),也可以使用缓存技术。
只要您控制可能发生的更改,我发现可以按照您的建议将user.name
缓存在评论表中。你可以通过在你的User
模型设置回调:
after_save do |user|
Comment.where(user_id: user.id).update_all(:username, user.name)
end
这种技术是不大不小的DB缓存,但是,当然,你可以缓存HTML片段。并且注释块对于缓存HTML块是一件好事。
因此,如果我限制返回的帖子(比如10),那么'@ comments'只会抓取10个返回帖子的用户? – DeanAlexRainier
@daanVOS我更新了我的例子。这会加载10个帖子,包括评论和评论用户全部热切。 – lebreeze
@daanVOS通过这种方式,应用程序可能会为帖子提供一个SQL查询,一个用于评论,另一个用于发表评论的用户,无论有多少评论。 – lebreeze