Skip to content
No description or website provided.
Ruby
Find file
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
lib
spec
test
.gitignore
.rspec
Gemfile
LICENSE
LICENSE.txt
README.md
Rakefile
activerecord-hstore_properties.gemspec

README.md

hstore-properties

Setup

Simply add following to your gemfile

gem 'hstore-properties'

Create properties column in the model you would like to use properties within, i.e.

rails g migration AddPropertiesToUsers properties:hstore

Apply your migration

rake db:migrate

Finally, describe your properties in your model file

class User < ActiveRecord::Base
  include ActiveRecord::HstoreProperties
  properties 'third_name', 
             'some_cool_feature' => :boolean, 
             'comments' => :counter,
             'age' => :number
end

Usage

Retrieving values

By default, all your properties are of type String. There are number of other property types available though...

  • string
  • boolean
  • number
  • counter
  • translation

More will come in near future...

All properties can be retrieved just as they are written into hstore column, by suffixing them with _property, i.e.

User.last.third_name_property #=> "Jack"

Booleans

Boolean properties, can be additionaly retrieved by using _enabled? and ? suffixes, that will cast them to boolean value, i.e.

User.last.some_cool_feature_enabled? #=> true
User.last.some_cool_feature? #=> true

What is more, you can toggle value of boolean property using _enable! / _raise! and _disable! / _lower! suffixes, e.g.

User.last.some_cool_feature_enable! #=> Changes property to true
User.last.some_cool_feature_raise! #=> Changes property to true
User.last.some_cool_feature_disable! #=> Changes property to false
User.last.some_cool_feature_lower! #=> Changes property to false

Counters

Counter properties, can be retrieved by using _count suffix, that will cast them to integer value, i.e.

User.last.comments_count #=> 10

What is more, it is possible to bump counter properties, i.e. following line will increment comments property by 1

User.last.comments_bump!

Translations

Translation kind of property allows you to store translated strings in properties column. The simplest way to store translation is just assign it a value, and it will save it in current locale, e.g.

class Category < ActiveRecord::Base
  include ActiveRecord::HstoreProperties
  properties 'caption' => :translation            
end

c = Category.last
c.caption = "Nice product" #this will save 'Nice product' into caption_en property 
c.save
c.caption_property #this will retrieve 'Nice product' from caption_en property 

You can always enforce in which locale you would like to store property, by suffixing it with any locale code available in I18n.available_locales

c = Category.last

c.caption_en = "Nice product" 
c.caption_nb_no = "Fint produkt" 

c.save

c.caption_property #=> "Nice product"
c.caption_nb_no #=> "Fint produkt" 

I18n.locale = :'nb-NO'
c.caption_property #=> "Fint produkt" 

Updating through forms

You obviously need to add :properties to yours attr_accessible

Below is an example of building appropriate fields dynamically with formtastic

<%= semantic_form_for @user do |f| %>
    <%= f.first_name %>
    <%= f.fields_for :properties, OpenStruct.new(@user.properties) do |builder| %>
        <% User.properties.each do |property| %>
            <%= builder.input property.name, property.formtastic_options %>
        <% end %>
    <% end %>
    <%= f.submit %>
<% end %>

Further customization

If most of your properties are of the same type, but other than string, you can overwrite default_property_klass to make other type default, i.e.

class User < ActiveRecord::Base
#...
  def self.default_property_klass
    ActiveRecord::Properties::BooleanProperty
  end
end

When to use?

  • If you consider adding redundant column to your table, that will only sometimes store any data
  • If you would like to make particular model "configurable"
  • If you will not likely perform queries on specific field but mostly read from it directly
Something went wrong with that request. Please try again.