Today I Learned

Rails 5 Attributes API + JSONb Postgres columns

As of when I'm writing this (Jan 2017), support for using ActiveRecord store with Postgres JSONb columns is a bit of shit-show. I'm planning to help fix it as soon as I have some time to spare, but for the moment if you want a better way of supporting these valuable column types in your Rails 5 app, use the new Attributes API. Plus get much improved performance with the Oj gem.

Here's how to make it work. First, define a :jsonb type to replace the native one.

class JsonbType < ActiveModel::Type::Value
  include ActiveModel::Type::Helpers::Mutable

  def type

  def deserialize(value)
    if value.is_a?(::String)
      Oj.load(value) rescue nil

  def serialize(value)
    if value.nil?

  def accessor

Next, register it in an initializer.

ActiveRecord::Type.register(:jsonb, JsonbType, override: true)

Note that the JsonbType class will need to be somewhere in your loadpath.

Now just declare the attribute at the top of your ActiveRecord model like this:

class User < ApplicationRecord
  attribute :preferences, :jsonb, default: {}

The "Bible" of Ruby on Rails is better than ever

For a limited time, get half off the ultimate The Rails 5 Way package

The "Future Proof Package" is available to TIL readers for only $20. It includes The Rails 5 Way, plus early access to Obie's next two books: Mastering The Rails Way and Testing The Rails Way

Looking for help? Obie Fernandez of Kickass Consulting has been the foremost industry expert on Ruby on Rails development for over 10 years. Rails is a core skill for each developer at Kickass Consulting and we'd love to take a look at your project. Contact us today and find out how we can help you.