Skip to content

petalmd/bright_serializer

Repository files navigation

Actions Status Gem Version Coverage Status

BrightSerializer

This is a very light and fast gem to serialize object in a Ruby project.

Installation

Add this line to your application's Gemfile:

gem 'bright_serializer'

And then execute:

$ bundle

Or install it yourself as:

$ gem install bright_serializer

Usage and features

Basic

Create a class and include BrightSerializer::Serializer

class AccountSerializer
  include BrightSerializer::Serializer
  attributes :id, :first_name, :last_name

  # With a block
  attribute :name do |object|
    "#{object.first_name} #{object.last_name}"
  end

  # With a block shorter
  attribute :created_at, &:to_s
end

AccountSerializer.new(Account.first).to_h
AccountSerializer.new(Account.first).to_json

Params

You can pass params to your serializer. For example to have more context with the authenticated user.

class AccountSerializer
  include BrightSerializer::Serializer
  attributes :id, :first_name, :last_name

  attribute :friend do |object, params|
    object.is_friend_with? params[:current_user]
  end
end

current_user = Account.find(authenticated_account_id)
AccountSerializer.new(Account.first, params: { current_user: current_user }).to_json

Conditional Attributes

Attribute can be remove from serialization by passing a proc to the option if. If the proc return true the attibute will be serialize. object and params or accessible.

class AccountSerializer
  include BrightSerializer::Serializer
  attributes :id, :first_name, :last_name

  attribute :email, if: proc { |object, params| params[:current_user].is_admin? }
end

Transform keys

By default, keys are not transformed.

class AccountSerializer
  include BrightSerializer::Serializer
  set_key_transform :underscore
end

set_key_transform :underscore # "first_name" => "first_name"
set_key_transform :camel # "first_name" => "FirstName"
set_key_transform :camel_lower # "first_name" => "firstName"
set_key_transform :dash # "first_name" => "first-name"

Instance serializer fieldsets

class AccountSerializer
  include BrightSerializer::Serializer
  attributes :id, :first_name, :last_name
end

# Only serialize first_name and last_name
AccountSerializer.new(Account.first, fields: [:first_name, :last_name]).to_json

Relations

has_one, has_many and belongs_to helper methods can be use to use an other serializer for nested attributes and relations.

  • The serializer option must be provided.

When using theses methods you can pass options that will be apply like any other attributes.

  • The option if can be pass to show or hide the relation.
  • The option entity to generate API documentation.
  • The option fields to only serializer some attributes of the nested object.
  • The option params can be passed, it will be merged with the parent params.
  • A block can be passed and the return value will be serialized with the serializer passed.
class FriendSerializer
  include BrightSerializer::Serializer
  attributes :id, :first_name, :last_name
end

class AccountSerializer
  include BrightSerializer::Serializer
  attributes :id, :first_name, :last_name

  has_many :friends, serializer: 'FriendSerializer'
end
# Block
has_one :best_friend, serializer: 'FriendSerializer' do |object, params|
 # ...
end

# If
belongs_to :best_friend_of, serializer: 'FriendSerializer', if: proc { |object, params| '...' }

# Fields
has_one :best_friend, serializer: 'FriendSerializer', fields: [:first_name, :last_name]

# Params
has_one :best_friend, serializer: 'FriendSerializer', params: { static_param: true }

# Entity
has_one :best_friend, serializer: 'FriendSerializer', entity: { description: '...' }

Entity

You can define the entity of your serializer to generate documentation with the option entity. The feature was build to work with grape-swagger. For more information about defining a model entity see the Swagger documentation.

class AccountSerializer
  include BrightSerializer::Serializer
  attribute :id, entity: { type: :string, description: 'The id of the account' }
  attribute :name

  has_many :friends, serializer: 'FriendSerializer',
    entity: {
      type: :array, description: 'The list the account friends.'
     }
end

Callable values are supported.

{ entity: { type: :string, enum: -> { SomeModel::ENUMVALUES } } }

For relations only type need to be defined, ref will use the same class has serializer.

has_many :friends, serializer: 'FriendSerializer', entity: { type: :array }
has_one :best_friend, serializer: 'FriendSerializer', entity: { type: :object }

Instance

If you have defined instance methods inside your serializer you can access them inside block attribute.

class AccountSerializer
  include BrightSerializer::Serializer
  attributes :id, :name

  attribute :print do |object|
    print_account(object)
  end

  def print_account(object)
    "Account: #{object.name}"
  end
end

Benchmark

Event if the main goal is not performance, it has very good result.

ruby benchmarks/collection.rb

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install.

New release

To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/petalmd/bright_serializer. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

The gem is available as open source under the terms of the MIT License.