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

Time:02-19

I have problem and I don't know how to solve it in a correct way. In my front-end app I have select which shows all products, so I need to send request to my Rails API. Controller has method index that sends all products, but with many different attributes and associations. I don't think so it's a good idea to send request to this method, because in <select> I need only product name and id. Example:

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

As u can see ProductSerializer send many things and it is expected but in a different view in FE app. In another page I need only id and name attributes to <select>. I know that I can create new Serializer and add if like this:

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

But I'm not sure is a good idea to create new Serializer only for one request, because in bigger application can be many situations like this. This if in index method dose not looks good too in my opinion, so maybe I should create new method for this request, but it's worth for one small request? Are there any good practices that can help to properly resolve such situations?

CodePudding user response:

I suggest you to try blueprinter. It a gem that help you to serializing your data and this gem is suitable with your needs.

To create the Blueprinter's serializer you can run this command in your terminal :

rails g blueprinter:blueprint Product

After You create the searializer, you may define different outputs by utilizing views:

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

After you define the view, now you can use the view in your controller. In your index action, you can call it with this syntax.

  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
  • Related