Shreddies - Stupid simple Rails model and object serializer
Shreddies is a JSON serialization library for Rails that focuses on simplicity and speed. No more "magic" DSL's - just plain old Ruby objects! It's primarily intended to serialize Rails models as JSON, but will also work with pretty much anything at all.
Shreddies primary principle is to be explicit. So a serializer will return nothing until you define some methods. This gives you complete control and everything is a known quantity - no surprises.
Installation
Add this line to your application's Gemfile:
gem 'shreddies'
And then execute:
$ bundle install
Or install it yourself as:
$ gem install shreddies
Usage
Serializers should be named after your models and located in "app/serializers
". Any public methods you define will be serialized, and you can quickly expose methods from the serialized subject using the delegate
class method, which simply delegates to the subject.
# app/serializers/user_serializer.rb
class UserSerializer < Shreddies::Json
delegate :id, :first_name, :last_name, :email
def name
"#{first_name} #{last_name}"
end
end
Calling the above will result in this JSON:
{
"id": 1,
"name": "Joel Moss",
"firstName": "Joel",
"lastName": "Moss",
"email": "me@you.com"
}
NOTE that all keys are transformed to camelCase, as the JSON is intended to be used by Javascript.
Call your serializer directly:
UserSerializer.render(user)
Or just use the #as_json
instance method on your model:
User.find(1).as_json
Model collections and array's are also supported:
User.all.as_json
Collection and Single Modules
You may find that you don't want or need to return as much data in collections of objects, or may want to include differtent data. So if a serializer defines a Collection
module, and a collection or array is being rendered, then that Collection module will automatically be included:
ArticleSerializer < Shreddies::Json
module Collection
def url
"https://blah.com/#{subject.slug}"
end
end
end
Conversely, you can define a Single
module, and that will be included when rendering a single object.
ArticleSerializer < Shreddies::Json
module Single
def body
'this body is really, really long, and I do not want it returned in lists.'
end
end
end
ActiveRecord Associations
ActiveRecord associations are supported with no additional work on your part. Shreddies will simply call #as_json
on any method that returns an ActiveRecord model or relation.
# app/serializers/user_serializer.rb
class UserSerializer < Shreddies::Json
delegate :articles
def latest_article
articles.latest
end
end
And if you need to be specific about what you render, just call the serializer or #as_json
directly:
# app/serializers/user_serializer.rb
class UserSerializer < Shreddies::Json
def articles
subject.articles.as_json index_by: :slug
end
def latest_article
LatestArticleSerializer.render articles.latest
end
end
before_render
callback
You can define a #before_render
private method in your serializers, which will act as a callback. It receives the object to be output, and expects you to return the object, which allows you to modify it before rendering.
Options
Both #as_json
and .render
accepts an options
hash, which will be forwarded to the serializer class, and available as options
. This allows you to pass arbitrary options and use them in your serializer.
The following standard options are supported, and provide additional built-in functionality:
serializer
By default #as_json
will look for a serializer named after your model. So a User
model will automatically use the UserSerializer
. Sometimes you want to use a different serializer class, in which case you can use the serializer
option:
User.all.as_json serializer: User::AdminSerializer
module
You can pass one or module names in the module
option, and these modules will be included into the serializer. This is great for selectively including attributes and methods.
Article.all.as_json module: :WithBody
ArticleSerializer < Shreddies::Json
module WithBody
def body
'This article body is really, really long'
end
end
end
The Collection
and Single
modules can be defined and they will be automatically included. The Collection module will be included when rendering an array or ActiveRecord collection (ActiveRecord::Relation
), and the Single module will be included when rendering a single obejct.
transform_keys
(default: true)
If false, the returned keys will not be transformed. The default is to deeply transform all keys to camelCase.
except
Pass one or more attribute names as a Symbol or Array of Symbols, and these will be excluded from the results:
User.all.as_json(except: [:first_name, :age])
only
Pass one or more attribute names as a Symbol or Array of Symbols, and ONLY these will be included in the results:
User.all.as_json(only: :first_name)
Attributes must still be defined within the Serializer.
index_by
Give this option a property of your serialized subject as a Symbol, and the returned collection will be a Hash keyed by that property.
User.all.as_json index_by: :id
{
1: {
"id": 1,
"name": "Joel Moss",
"firstName": "Joel",
"lastName": "Moss"
}
2: {
"id": 2,
"name": "An Other",
"firstName": "An",
"lastName": "Other"
}
...
}
Serializer Inheritance
A serializer can inherit from any other serializer, which is a great way to create custom views:
# app/serializers/user_serializer.rb
class UserSerializer < Shreddies::Json
delegate :id, :first_name, :last_name, :email
def name
"#{first_name} #{last_name}"
end
end
class User::AdministratorSerializer < UserSerializer
def type
'administrator'
end
end
Then call it like any other serializer:
User::AdministratorSerializer.render(user)
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake test
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
. 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/joelmoss/shreddies. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the Shreddies project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.