簡體   English   中英

在 ActiveRecord 集合中包含關聯模型的屬性

[英]Include associated model's attributes in ActiveRecord collection

我試圖以每個博客文章對象都具有所有關聯數據的方式來構建我的博客文章列表。 我需要它的結構是這樣的,因為我將數據交給我的 JavaScript 前端。

我需要一個具有與此類似的簡單條目的數據結構:

[
<BlogPost id: 12,
  image: "image.png",
  title: "corrupti",
  content: "\n## Fuga eveniet beatae necessitatibus excepturi c...",
  blog_author: {
    id: 8,
    name: "Theodan Wells"
  },
  blog_category: {
    id: 6,
    name: "Marketing"
  }>
]

這些關聯可能很明顯,但無論如何這里是我的模型:

class BlogPost < ApplicationRecord
  belongs_to :blog_author, inverse_of: :blog_posts
  belongs_to :blog_category, inverse_of: :blog_posts
end

class BlogAuthor < ApplicationRecord
  has_many :blog_posts, inverse_of: :blog_author
end

class BlogCategory < ApplicationRecord
  has_many :blog_posts, inverse_of: :blog_category
end

我確定我需要使用includesjoins ,然后以某種方式提取屬性以將它們包含在集合中,但我不確定如何使用。

我知道如何通過使用collectmap手動形成數據結構來做到這一點,但上次我使用這些方法時,它使我的服務器響應速度減慢了十倍。 當我上次取出 collect 語句時,實際上從 8s 變成了 0.8s。

您可以通過覆蓋as_json方法來做到這as_json ,如下所示:

class BlogPost < ApplicationRecord
  belongs_to :blog_author, inverse_of: :blog_posts
  belongs_to :blog_category, inverse_of: :blog_posts

  def as_json(options = {})
    if options[:index]
      {
          id: id,
          image: image,
          title: title,
          content: content,
          blog_author: {
                         id: blog_author.id,
                         name: blog_author.name
                       },
          blog_category: {
                         id: blog_category.id,
                         name: blog_category.name
                          }
      }
    else
      super
    end
  end

end

然后以as_json結尾調用BlogPost ,同時添加includes這樣它就會一次性從關聯中獲取數據,如下所示:

BlogPost.includes(:blog_author,:blog_category).as_json(index: true)

注意:
如果關聯中有很多字段,那么最好將select with joins添加到查詢中以選擇確切的字段,如下所示:

    BlogPost.joins(:blog_author,:blog_category)
            .select("blog_posts.id,blog_posts.image,blog_posts.content ,blog_posts.title, blog_authors.id, blog_authors.name, blog_categories.id, blog_categories.name")
            .as_json(index: true)

如果您有性能問題,可以使用deep_pluck 它可以在不加載一堆記錄的情況下提取數據。 因此比使用as_jsonas_json

BlogPost.deep_pluck(
  :id, 
  :image, 
  :title, 
  :content,
  blog_author: [:id, :name],
  blog_category: [:id, :name],
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM