No commit activity in last 3 years
No release in over 3 years
Enhances ActiveModel::Serializers gem by adding support for serializers namespacing. This makes developing versioned APIs super easy. Works with ActiveModel::Serializers 0.8.x series.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 1.7
>= 0
>= 3.2
~> 10.0

Runtime

 Project Readme

ActiveModelSerializer::Namespaces

Version Issues Build Climate Coverage

Compatibility note

This gem is designed for Active Model Serializers 0.8.x only. It won't be updated for 0.9 neither for 0.10 due to fundamental architecture changes in Active Model Serializers.

When is it useful?

Short answer: when you need more than one way to serialize your models and you want to organize that in namespaces.

One example is that your application is serving a versioned API. You want to freeze the old APIs and actively develop upcoming version.

Another example is that your application is utilizing few 3rd-party services which expect JSONs as input, so you need to convert your models somehow, preferably avoiding mixing different representations for various integrations.

In all these cases the most natural approach is to define a separate set of serializers for every API version or integration. But then you discover that you need to pass serializer name every time you use it. Even #has_many declarations in serializers require that. And what will you do to serialize a collection of objects of different classes?

With ActiveModelSerializer-Namespaces, you can nest your serializers in modules with no pain. Just pass namespace of your choice and it will be used throughout complex models and collections. What's more, you don't need to type it in every controller action, it's enough to specify it as default in a base controller or mixin module once for the whole API version.

Creating new API version is as easy as copying code to new location.

How do I use it?

Given:

class Article < ActiveRecord::Base
end

module V1
  class ArticleSerializer < ActiveModel::Serializer
  end
end

Either specify namespace directly at render call:

def some_action
  render json: article, serialization_namespace: Ver1
end

Or set it as a default option in controller:

def some_action
  render json: article
end

def default_serializer_options
  {serialization_namespace: Ver1}
end

See spec/features_spec.rb for more detailed examples.

How does it work (caveats)?

The trick is to delay inferring serializer class until #new is called and the options hash is available.

To achieve that, ::active_model_serializer is defined for all models which returns a finder proxy object instead of serializer class. The finder instance responds to #new call as would the real class, but it performs a lookup for correct serializer class before instantiating a serializer object. This way it's fully transparent for Active Model Serializer internals.

As a consequence, overriding #active_model_serializer or ::active_model_serializer disables this gem for given model.

Why is it a separate gem?

I did want to solve one of the biggest drawbacks of Active Model Serializers 0.8. I didn't want to introduce backwards-incompatible changes into it's API.

Contributing

Fork it, improve it then create a pull request. You know the drill.

See also