Rails 6 API 发送和序列化数据的最佳做法是什么?

Rails 6 API What are good practices for sending and serializing data?

我有问题,我不知道如何以正确的方式解决它。在我的前端应用程序中,我有 select 显示所有产品,因此我需要向我的 Rails API 发送请求。控制器具有发送所有产品的方法索引,但具有许多不同的属性和关联。我不认为向此方法发送请求是个好主意,因为在 <select> 中我只需要产品名称和 ID。示例:

ProductController.rb

 def index
   render json: @products, include: 'categories, user.company'
 end

ProductSerializer.rb

class ProductSerializer < ActiveModel::Serializer
  attributes :id, :name, :desc, :weight, :amount, ...

  belongs_to :user
  has_many :categories
end

如您所见,ProductSerializer 发送了很多东西,这是预期的,但在 FE 应用程序中的视图不同。在另一个页面中,我只需要 <select> 的 id 和 name 属性。我知道我可以创建新的 Serializer 并像这样添加 if

  def index
    render json: @product, each_serializer: ProductSelectSerializer and return if pramas[:select]
    render json: @products, include: 'categories, user.company'
  end

但我不确定只为一个请求创建新的 Serializer 是个好主意,因为在更大的应用程序中可能有很多这样的情况。在我看来,索引方法中的 if 看起来也不太好,所以也许我应该为这个请求创建新方法,但对于一个小请求来说值得吗?有什么好的做法可以帮助妥善解决此类情况?

我建议你试试blueprinter。它 gem 可以帮助您序列化数据,而这个 gem 适合您的需要。

要创建 Blueprinter 的序列化程序,您可以 运行 在您的终端中使用此命令:

rails g blueprinter:blueprint Product

创建 searializer 后,您可以使用视图定义不同的输出:

class ProductBlueprint < Blueprinter::Base
  identifier :id

  view :normal do
    field :product_name
  end

  view :extended do
    fields :product_name, :product_price
    association :user, blueprint: UserBlueprint
    association :categories, blueprint: CategoryBlueprint 
    # this will take the association from your product's model and make sure you have created the CategoryBlueprint and UserBlueprint
  end
end

定义视图后,现在您可以在控制器中使用视图了。在您的索引操作中,您可以使用此语法调用它。

  def index
    render json: ProductBlueprint.render_as_hash(@product, view: :normal) and return if params[:select]
    render json: ProductBlueprint.render_as_hash(@products, view: :extended)
  end