如何避免N + 1?

时间:2014-07-16 15:19:37

标签: ruby-on-rails activerecord ruby-on-rails-4 active-model-serializers

我正在为移动社交网络应用程序构建JSON API,用户可以拥有一些帖子以及其他能够喜欢这些帖子的用户和评论。

class Post < ActiveRecord::Base
  belongs :user
end

class Like < ActiveRecord::Base
  belongs :user
  belongs :post, counter_cache: true
end

class PostSerializer < ActiveModel::Serializer
  attributes :id, :description, :likes_count, :is_liked

  def likes_count
    object.likes.size   # should pull from counter_cache
  end

  # did current_user already like this post
  def is_liked
    object.likes(user_id: scope.id).exists?  # N+1
  end
end

class PostsController < ApplicationController
  def index
    @posts = Post.recent
    render json: @posts, each_serializer: PostSerializer
  end
end

# Output of JSON API to mobile client
{
  "id": 1,
  "body": "...",
  "likes_count": 10,
  "is_liked": true
}

用户登录移动客户端并在打开应用程序时发出获取最新帖子的请求,但是为了能够使用标记is_liked生成JSON帖子响应,我们需要发出查询以将数据库命中为能够要知道用户是否已经喜欢这个帖子,那么在移动屏幕上我们会在屏幕上的每个帖子上显示该状态。

1 个答案:

答案 0 :(得分:0)

我在这里遇到了同样的问题,所以让我们看看我是否可以帮助你......

belongs_to :post, counter_cache: true模型中添加Like时,您必须在名为posts类型likes_count的{​​{1}}表格中添加一列。

另外,请注意,当您创建或删除integer时,计数器缓存会递增或递减,因此如果like中有一些data,它将无效。你必须reset the counters

我希望它有所帮助...