PostgresExt-Serializers
This Gem patches the ArraySerializer in Active Model Serializers to offload JSON serialization to PostgreSQL, which is much faster and more memory efficient than serialization in Ruby.
Instead of instantiating lots of ActiveRecord models, which are then serialized to a hash using ActiveModel Serializers and finally converted to JSON, this Gem builds the entire JSON in the database and returns it as a single string that can be passed through to the client unmodified.
How does it work?
You can read Avoid Rails When Generating JSON responses with PostgreSQL by Dan McClain on the DockYard Blog or watch a YouTube video of his Postgres Open 2014 Talk Using PostgreSQL, not Rails, to make Rails faster (Slides) to understand how this Gem works under the hood.
Supported Versions
This gem currently only works with the older active_model_serializers 0.8.x and activerecord 4.0/4.1/4.2. For activerecord 4.2 support you need at least postgres_ext version 2.4.0.
You must be using at least Postgres 9.2, but 9.4 or later is recommended.
Support for newer AMS versions might be added in the future.
Looking for help?
If it is a bug please open an issue on
Github. If you need
help using the gem please ask the question on
Stack Overflow. Be sure to tag the
question with DockYard
so we can find it.
Installation
Add this line to your application's Gemfile:
gem 'postgres_ext-serializers'
And then execute:
$ bundle
Or install it yourself as:
$ gem install postgres_ext-serializers
Usage
Just require 'postgres_ext/serializers'
and use
ActiveModel::Serializers as you normally would!
Postgres_ext-serializers will take over anytime you try to serialize an
ActiveRecord::Relation.
Methods in Serializers and Models
If you are using methods to compute properties for your JSON responses
in your models or serializers, postgres_ext-serializers will try to
discover a SQL version of this call by looking for a class method with
the same name and the suffix __sql
. Here's an example:
class MyModel < ActiveRecord::Base
def full_name
"#{object.first_name} #{object.last_name}"
end
def self.full_name__sql
"first_name || ' ' || last_name"
end
end
class MySerializer < ActiveModel::Serializer
def full_name
"#{object.first_name} #{object.last_name}"
end
def full_name__sql
"first_name || ' ' || last_name"
end
end
There is no instance of MyModel created so sql computed properties needs to be a class method. Right now, this string is used as a SQL literal, so be sure to not use untrusted values in the return value.
Note: Postgres date, timestamp or timestamptz format
Postgres 9.2 and 9.3 by default renders dates according to the current DateStyle Postgres setting, but many JSON processors require dates to be in ISO 8601 format e.g. Firefox or Internet Explorer will parse string as invalid date with default DateStyle setting. Postgres 9.4 onwards now uses ISO 8601 for JSON serialization instead.
Developing
To work on postgres_ext-serializers locally, follow these steps:
- Run
bundle install
, this will install (almost) all the development dependencies - Run
gem install byebug
(not a declared dependency to not break CI) - Run
bundle exec rake setup
, this will set up the.env
file necessary to run the tests and set up the database - Run
bundle exec rake db:create
, this will create the test database - Run
bundle exec rake db:migrate
, this will set up the database tables required by the test - Run
BUNDLE_GEMFILE='gemfiles/Gemfile.activerecord-4.2.x' bundle install --quiet
to create the Gemfile.lock. - Run
bundle exec rake test:all
to run tests against all supported versions of Active Record (currently 4.0.x, 4.1.x, 4.2.x)
Authors
We are very thankful for the many contributors
Versioning
This gem follows Semantic Versioning
Want to help?
Please do! We are always looking to improve this gem.
Legal
DockYard, Inc Β© 2014