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
:jsonb
end
def deserialize(value)
if value.is_a?(::String)
Oj.load(value) rescue nil
else
value
end
end
def serialize(value)
if value.nil?
nil
else
Oj.dump(value)
end
end
def accessor
ActiveRecord::Store::StringKeyedHashAccessor
end
end
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: {}