Last Updated: February 25, 2016
·
2.934K
· stereoscott

Using PostgreSQL's hstore with Rails 4: boolean properties, too!

Rails 4 supports a few native PostgreSQL types including hstore.

With a little bit of meta-programming you can really soup up your models to store various properties without having to run database migrations. Here are my two favorite techniques. The first allows you to check and set boolean properties, the second is general purpose. You also get scopes like has_xxx('value') which is useful when querying your data.

Boolean Properties

%w[display_redemption_code display_order_number].each do |key|
 scope "has_#{key}", ->(value) { where("properties @> hstore(?, ?)", key, value) }

 define_method("#{key}?") do
 if properties && properties[key].present? then 
 ActiveRecord::ConnectionAdapters::Column.value_to_boolean(properties[key]) 
 else 
 nil
 end
 end

 alias_method "#{key}".to_sym, "#{key}?".to_sym 

 define_method("#{key}=") do |value|
 self.properties = (properties || {}).merge(key => value)
 end
end

Other Property Types

%w[products_title].each do |key|
 scope "has_#{key}", ->(value) { where("properties @> hstore(?, ?)", key, value) }

 define_method(key) do
 properties && properties[key]
 end

 define_method("#{key}=") do |value|
 self.properties = (properties || {}).merge(key => value)
 end
end 

More details on how to enable hstore: http://platformonrails.wordpress.com/2013/03/17/enabling-postgresql-hstore-with-rails-4/