Economy of Effort

Twitter LinkedIn GitHub Mail RSS

PostgreSQL Hstore Default Value in Rails 4

Having used activerecord-postgres-hstore before native hstore support was added to Rails 4, I was used to the behavior of empty hstore fields returning an empty hash {} when a row with such a field was instantiated into an ActiveRecord object, as was discussed and added in the gem’s issue #22.

This behavior changed in Rails 4’s hstore support. An ActiveRecord object with an empty hstore field will return nil for that field rather than an empty hash. (When someone opened a bug in the Rails repo to suggest implementing the same behavior in the new native hstore support, it was brushed off.)

By default, that leaves us to have to nil-check every hstore property in our objects before accessing any keys (eg. @myobj.data && @myobj.data['mykey']). However, we can get our “empty” hstore fields instantiating as empty hashes instead of nil with a tweak of our migration.

Simply add default: '', null: false to the migration, eg.

class AddDataToThings < ActiveRecord::Migration
def change
add_column :things, :data, :hstore, default: '', null: false
end
end

With that default in place, our empty hstore fields will instantiate as empty hashes, and we can avoid the nil check:

[1] pry(main)> thing = Thing.new
=> #<Thing id: nil, ... >
[2] pry(main)> Thing.data
=> {}

Comments