【问题标题】:How to merge two models with one-to-many relation in Rails?如何在 Rails 中合并两个具有一对多关系的模型?
【发布时间】:2018-02-16 19:37:22
【问题描述】:

我有两个模型,比如说AuthorBook,其中Author 有很多Books。我必须通过 AJAX 获取 Authors 的名称列表及其各自的 Bookss 名称。

我有一些想法,但不知道哪个最好。

  1. 独立获取它们(所有 Authors 和 Books 并使用过滤器在 JavaScript 中对它们进行分组),但似乎将应该由服务器完成的工作放在 JavaScript 上。
  2. 创建一个包含AuthorBooks 数组的ruby 类/结构。查询 Authors 并为每个查询分别查询 Books,但这似乎是不必要的许多数据库查询。
  3. 与上述相同,但不是包装类,而是获取 Authors 的属性散列并插入 Books 的属性散列数组。多个查询的问题与上述相同。
  4. 最好在一个查询中以某种方式连接表,以检索所有已与其Books 合并的Authors。类似 sql join 的东西,但用于一对多关系(如果这种关系存在的话)。

【问题讨论】:

  • 您是否已经查看过active_model_serializer
  • 不,我没有。我花了很多时间googlong这个问题,这是我第一次听到这个名字。我现在研究一下,谢谢。

标签: ruby-on-rails ruby model rails-activerecord


【解决方案1】:

Active Model Serializer 是一种快速简便的解决方案。它将您的数据序列化为 json,并提供对您要显示的属性的完全控制。

在您的 gemfile 中:

gem 'active_model_serializers'

然后运行以下命令:

bundle install
rails g serializer Author
rails g serializer Book

现在您将生成 2 个新文件。

author_serializer.rb

class AuthorSerializer < ActiveModel::Serializer
  attribute :id  
  # add your other author attributes here such as:
  # attribute :name
  # attribute :age
  has_many :books
end

book_serializer.rb

class BookSerializer < ActiveModel::Serializer
  attribute :id  
  # add your other book attributes here such as:
  # attribute :title
  # attribute :publisher
end

authors_controller.rb

class AuthorsController < ApplicationController

  def index
    render status: :ok, 
           json: Author.all, 
           each_serializer: AuthorSerializer
  end

  def show
    render status: :ok, 
           json: Author.find(params[:id]), 
           serializer: AuthorSerializer
  end
end

注意索引指定each_serializer,显示指定serializer

【讨论】:

    【解决方案2】:

    你可以这样做

    Author.includes(:books)
    

    这将生成两个查询,一个针对作者,一个针对书籍,您将获得一个“作者”对象的集合,每个对象都有一个“书籍”集合。

    【讨论】:

      【解决方案3】:

      要将Authors 和Books 序列化为JSON,您可以将include 参数提供给to_json

      class SomeJsonController < ApplicationController
        def show
          author = Author.find(params[:id])
          respond_to do |format|
            format.json { render json: author.to_json(include: :books) }
          end
        end
      end
      

      完整文档可在here 获得。 active_model_serializer 也可以工作(如果您将有一堆需要为关联呈现 JSON 的此类案例,则可以更好地扩展)但如果您只有一个案例,则可能会过大。

      【讨论】:

        猜你喜欢
        • 2014-03-01
        • 1970-01-01
        • 2013-05-30
        • 2021-05-08
        • 1970-01-01
        • 2019-05-25
        • 1970-01-01
        • 2015-03-16
        • 1970-01-01
        相关资源
        最近更新 更多