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
我有问题,我不知道如何以正确的方式解决它。在我的前端应用程序中,我有 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