【问题标题】:How to avoid N+1?如何避免N+1?
【发布时间】:2014-07-16 15:19:36
【问题描述】:

我正在为移动社交网络应用程序构建 JSON API,用户可以发布一些帖子,而其他用户可以在这些帖子上点赞和 cmet。

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 帖子响应,我们需要发出查询以命中 DB 才能知道如果用户已经喜欢该帖子,那么在移动屏幕上,我们会在屏幕上的每个帖子上显示该状态。

【问题讨论】:

  • 您是否考虑过在 Redis 之类的东西中缓存喜欢的内容?您可以做的另一件事是将liked_by? 抽象为Post 模型中的类方法,然后只进行查询,直到达到它无法扩展的点,然后您可以使用Redis 或任何轻松地在其中插入一些缓存其他平台

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


【解决方案1】:

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

当您在Like 模型中添加belongs_to :post, counter_cache: true 时,您必须在posts 表中添加一个名为likes_count 类型integer 的列。

另外,请注意,当您创建或删除like 时,计数器缓存会增加或减少,因此如果您的database 中有一些data,它将不起作用。你必须reset the counters

希望对你有帮助……

【讨论】:

    猜你喜欢
    • 2018-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多