ActiveRecord plugin: has_many_booleans

has_many_booleans creates virtual boolean attributes for a model. When the object gets saved, the plugin transforms all attributes into a single integer, using a bitset[http://rbjl.net/2-storing-an-array-of-indices-in-an-integer]. So you can easily add new attributes without changing the database structure.

Setup

Install the plugin with:

rails plugin install git://github.com/janlelis/has_many_booleans

or as a gem:

gem install has_many_booleans # and add it to your Gemfile

Add an integer field with the name booleans to your the model’s database table.

Example usage

You simply list names for the desired booleans in the model.rb file…

class Model < ActiveRecord::Base
  has_many_booleans :name, :password
end

…to get the following methods:

name_activated, name_activated?

get the value of the boolean

name_activated!

set the value to true

name_activated= value

set the value to false or true

password_activated, …

same methods for :password

When saving the object, all “virtual” booleans get converted to a single integer that is saved in the database. Vice versa, when loading an model from the database, its boolean integer sets the value of the above methods.

Example 2: basic options

class Model < ActiveRecord::Base
  has_many_booleans :name, :password,
          :true => [:name],
          :append => 'set',
end

The default values of all booleans is false. However, with the :true option, you can list those booleans, which should default to true.

The :append option lets you modify the suffix to append to the boolean names.

Example 3: advanced options

class Model < ActiveRecord::Base
  has_many_booleans :name, :password,
          :field => 'some_db_field',
          :lazy  => false,
          :self  => 'model_available',
          :self_value => true,
          :unkown_value => false,
end

The :field option lets you change the database field in which the integer gets stored (default is booleans).

When the :lazy option is set to false, the bitset integer gets changed every time you assign a new value for a boolean. The default setting is true, which means, the integer does not get updated until the object is saved in the database.

The :self option is just another virtual boolean, which’s method name you can freely assign.

The :unknown_value is the new value for booleans, which are assigned a new value, but it is not in the :false_values or :true_values option arrays. Default is true, set it to false to get ActiveRecord behaviour.

The default false_ and true_values are the same as in ActiveRecord.

Scopes

The plugin also generates a .true and a .false scope for the model. You have to pass a boolean name as parameter to filter for this value. If you pass multiple boolean names, they get connected with ‘or’. To get an ‘and’ condition, chain multiple scopes. If you don’t pass any boolean names (or nil), the special :self boolean is meant.

Example queries

Model.true(:name)   # scopes to all models, where :name is true
Model.false         # scopes to all models, where the :self boolean is false
Model.true(:name, :password)      # :name or :password must be true
Model.true(:name).true(:password) # :name and :password must be true

Further reading

For a more detailed description of the options, see the rdoc for the has_many_booleans method.

Copyright © 2010-2011 Jan Lelis, rbjl.net, released under the MIT license

Contributions by jellehelsen