Rails:使用关联模型渲染JSON

时间:2017-12-04 16:45:19

标签: ruby-on-rails json

如果这是一个愚蠢的问题我很抱歉,但是我在合理的时间内渲染JSON时遇到了麻烦。我觉得我忽略了一些简单的事情。这是Angular 2 SPA的API端点。

我有一个书签模型, has_many 标签

class Bookmark < ApplicationRecord
  has_many :taggings
  has_many :tags, through: :taggings
end

想法是用户登录,并显示其书签 - 分页 - 每个书签都显示其关联的标记

问题是我遇到了n + 1查询问题。有了数千个对象,它需要2分钟的时间才能渲染JSON。这导致我安装 bullet gem 并使用预先加载。

# bookmarks_controller.rb
def index
  @bookmarks = Bookmark.includes(:taggings, :tags).where(user_id: @current_user.id).order('created_at DESC')

  render json: @bookmarks, :include => :tags
end

所以这加快了查询的时间,但实际的渲染过程仍然需要永远。

此时,我尝试使用 Oj gem 来优化JSON。这大大提高了渲染速度!

def index
  @bookmarks = Bookmark.where(user_id: @current_user.id).order('created_at DESC')

  render json: Oj.dump(@bookmarks, mode: :compat)
end

这里的问题是bullet gem建议删除急切加载,而 Oj不会呈现关联的标签。如果我包含急切的加载,它仍然需要大约2分钟加载,这是荒谬的。我似乎无法找到任何关于包含关联的文档。

如何更快地将包含在关联的代码中?这个想法是否可行或者我应该改变方向吗?

任何帮助将不胜感激!我已经在我的桌子上敲了好几天了。如果您需要更多信息,请告诉我,我很乐意提供。

编辑以下是请求的表格:

create_table "bookmarks", force: :cascade do |t|
  t.string "name"
  t.string "url"
  t.boolean "reading_list"
  t.bigint "user_id"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.integer "view_count", default: 0
  t.integer "folder_id"
  t.boolean "is_favorite", default: false
  t.index ["user_id"], name: "index_bookmarks_on_user_id"
end

create_table "tags", force: :cascade do |t|
  t.string "name"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

create_table "taggings", force: :cascade do |t|
  t.bigint "tag_id"
  t.bigint "bookmark_id"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.bigint "folder_id"
  t.index ["bookmark_id"], name: "index_taggings_on_bookmark_id"
  t.index ["folder_id"], name: "index_taggings_on_folder_id"
  t.index ["tag_id"], name: "index_taggings_on_tag_id"
end

add_foreign_key "taggings", "bookmarks"
add_foreign_key "taggings", "folders"
add_foreign_key "taggings", "tags"

0 个答案:

没有答案