1

我有一个包含用户、帖子和评论的应用程序。用户 has_many Posts, Posts has_many Comments and Comments belongs_to Users and Posts。

在我的视图模板中,我正在循环这样的评论以获取评论者的用户名:

User.find(comment.user_id).name

如果我对每个帖子的每个评论都这样做,效率如何?我可以想象将用户名存储在 Comments 表的单独行中可能会更快,但复制数据似乎是错误的。

我是偏执狂,ActiveRecord 是在做一些缓存魔法还是有更好的方法来做这样的事情?

4

4 回答 4

0

If performance is an issue for you, using a none relational DB, like Mongodb is the way to go.

If you still want to use ActiveRecord, either you use eager loading with Post.comments.include(:user) (which will load unused users info - and that's not great), or you can use caching techniques.

I find it OK to cache the user.name in the comments table, as you suggested, as long as you control the changes that can occur. You can do that by setting callbacks in your User model:

after_save do |user|
  Comment.where(user_id: user.id).update_all(:username, user.name)
end

This technique is sort of a DB caching, but, of course, you can cache HTML fragments. And a comment block is a good to cache HTML block.

于 2012-07-04T10:11:44.340 回答
0

渴望加载关联

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
于 2012-07-04T09:28:25.917 回答
0

您可以在初始查询中预加载用户。看到您在 User 和 Comment 之间设置了关联,您可以通过关联访问用户。

假设您有一个控制器方法:

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
于 2012-07-04T09:29:44.847 回答
0

修改

如果您有如下关联,则可以从评论对象本身访问用户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
于 2012-07-04T09:30:17.837 回答