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
endCalling 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_jsonModel collections and array's are also supported:
User.all.as_jsonCollection 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
endConversely, 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
endActiveRecord 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
endAnd 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::AdminSerializermodule
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: :WithBodyArticleSerializer < Shreddies::Json
module WithBody
def body
'This article body is really, really long'
end
end
endThe 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
endThen 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.