Skip to main content

Attributes

Attributes allow you to specify which record attributes you want to serialize.

There are two types of attributes:

  • Field - simple columns defined on the record it self.
  • Virtual/Method - this allows to include properties beyond simple fields.

class UserSerializer < Panko::Serializer
attributes :full_name

def full_name
"#{object.first_name} #{object.last_name}"
end
end

Field Attributes

Using field attributes you can control which columns of the given ActiveRecord object you want to serialize.

Instead of relying on ActiveRecord to do it's type casting, Panko does on it's own for performance reasons (read more in Design Choices).

Method Attributes

Method attributes are used when your serialized values can be derived from the object you are serializing.

The serializer's attribute methods can access the object being serialized as object:


class PostSerializer < Panko::Serializer
attributes :author_name

def author_name
"#{object.author.first_name} #{object.author.last_name}"
end
end

Another useful thing you can pass your serializer is context, a context is a bag of data whom your serializer may need.

For example, here we will pass feature flags:


class UserSerializer < Panko::Serializer
attributes :id, :email

def feature_flags
context[:feature_flags]
end
end

serializer = UserSerializer.new(context: {
feature_flags: FeatureFlags.all
})

serializer.serialize(User.first)

Filters

Filters allows us to reduce the amount of attributes we can serialize, therefore reduce the data usage & performance of serializing.

There are two types of filters:

  • only - use those attributes only and nothing else.
  • except - all attributes except those attributes.

Usage example:


class UserSerializer < Panko::Serializer
attributes :id, :name, :email
end

# this line will return { 'name': '..' }
UserSerializer.new(only: [:name]).serialize(User.first)

# this line will return { 'id': '..', 'email': ... }
UserSerializer.new(except: [:name]).serialize(User.first)

> Note that if you want to user filter on an associations, the :name property is not taken into account. If you have a has_many :state_transitions, name: :history association defined, the key to use in filters is :state_transitions (e.g. { except: [:state_transitions] }).

Filters For

Sometimes you find yourself having the same filtering logic in actions. In order to solve this duplication, Panko allows you to write the filters in the serializer.


class UserSerializer < Panko::Serializer
attributes :id, :name, :email

def self.filters_for(context, scope)
{
only: [:name]
}
end
end

# this line will return { 'name': '..' }
UserSerializer.serialize(User.first)

> See discussion in: https:

Aliases

Let's say we have an attribute name that we want to expose to client as different name, the current way of doing so is using method attribute, for example:


class PostSerializer < Panko::Serializer
attributes :published_at

def published_at
object.created_at
end
end

The downside of this approach is that created_at skips Panko's type casting, therefore we get a direct hit on performance.

To fix this, we can use aliases:


class PostSerializer < Panko::Serializer
aliases created_at: :published_at
end