-1

Just as the title says, how should I sort the api using the attribute in Active Model Serializer in Rails?

I have an example api consist of shopping list. It consist product name, location, and price. In my Serializer

class ShoppingListSerializer < ActiveModel::Serializer
  attributes :id, :name, :location, :price

  def id
    Product.find(object.product_id).id
  end

  def name
    Product.find(object.product_id).name
  end

  def location
    Product.find(object.product_id).location
  end

  def price
    Product.find(object.product_id).price
  end
end

I want to sort it using the attribute name. How should I do that? Thank you.

  • 1
    Sort the api, what do you mean by that? Also, doing `Product.find...` in every method seems very inefficient. What is the problem you are actually trying to solve here? – Eyeslandic Jul 22 '21 at 07:02
  • 1
    This sounds like a textbook X & Y problem. You don't sort in a serializer. Neither should you be doing DB queries. A serializer is really just like a view. It takes data from the controller and transforms it into JSON. – max Jul 22 '21 at 14:55

1 Answers1

0

In your example you're not serializing the shopping list, you are serializing products.

I'd recommend doing something like:

in controller -

def serialize_products_from(shopping_list)
  ActiveModelSerializers::SerializableResource.new(
    shopping_list.products,
    each_serializer: ProductSerializer
  )
end

Having in mind your shopping_list object has many products. If attributes id/name/location/price are database columns on Product table, you don't need to define methods for them. You only define methods when you need to manipulate the output given by serializer.

in serializer -

class ProductSerializer < ActiveModel::Serializer
  attributes :id, :name, :location, :price

  def price_in_dollars
    "#{object.price / 100},#{object.price % 100}"
  end
end

you can later try to sort the results

serialize_products_from(shopping_list).sort

Or try to proceed from here with some other solutions.

LE-HU
  • 631
  • 5
  • 17