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