Bitmasker allows you to store many boolean values as one integer field in the database.
Ruby
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
lib
test
.gitignore
.travis.yml
Gemfile
MIT-LICENSE
README.md
Rakefile
bitmasker.gemspec

README.md

Bitmasker

Bitmasker allows you to store many boolean values as one integer field in the database.

Synopsis

  class User < ActiveRecord::Base
    has_bitmask_attributes :notifications do |config|
      config.attribute :send_weekly_newsletter,    0b0001
      config.attribute :send_monthly_newsletter,   0b0010, true
    end
  end

Code Climate Build Status

Examples

  # in migration
  t.integer :notifications_mask

  # in app/models/user.rb
  class User < ActiveRecord::Base
    has_bitmask_attributes :notifications do |config|
      config.attribute :send_weekly_newsletter,    0b0001
      config.attribute :send_monthly_newsletter,   0b0010, true
      config.attribute :send_daily_update,         0b0100
      config.accessible
      # config.field_name :notifications_mask # <- default functionality
    end
  end

This will define the following methods:

  • User#notifications -- returns a BitmaskAttributes object representing all values
  • User#send_weekly_newsletter? -- predicate
  • User#send_weekly_newsletter -- works just like the predicate, makes it easy to use actionview form helpers
  • User#send_weekly_newsletter=(value) -- just give it a boolean value (also takes "0" and "1" or "t" and "f" just like activerecord does for boolean fields)
  • User#send_monthly_newsletter?
  • User#send_monthly_newsletter
  • User#send_monthly_newsletter=(value)

the call to config.accessible calls attr_accessible :send_weekly_newsletter, :send_monthly_newsletter in your model.

Scopes

Bitmasker also sets up a few useful scopes:

  • User#with_notifications
  • User#without_notifications
  • User#with_any_notifications

Scopes Examples

# Users that want weekly newsletter
User.with_notifications(:send_weekly_newsletter)

# Users that want monthly AND weekly newsletters
User.with_notifications(:send_monthly_newsletter, :send_weekly_newsletter)

# Users that want monthly OR weekly newsletters
User.with_any_notifications(:send_monthly_newsletter, :send_weekly_newsletter)

View Example

  # in your view
  <% form_for @user do |f| %>
    Monthly Newsletter: <%= f.check_box :send_monthly_newsletter? %>
    or
    Monthly Newsletter
    Yes: <%= f.radio_button :send_monthly_newsletter, 'true' %>
    No: <%= f.radio_button :send_monthly_newsletter, 'false' %>
  <% end %>

Config Options

config.attribute(name, mask, default = false)

Sets up a binary attribute. Defines three functions: name, name?, and name=(true|false)

  • name a symbol, Bitmasker will define
  • mask example: 0b0000001, must be a power of 2
  • default set to true if you want the attribute to default to true

config.accessible if you are using attr_accessible in your model and you want to mass-assign your bitmask attributes, you will want to call this

config.field_name(name)

  • name name of the field name in the database where all this info is stored, should be an integer

Updating from has_bitmask_attributes

If you used the method_format feature from has_bitmask_attributes, you will need to change your configuration as method_format has been removed.

Before

  # in app/models/user.rb
  class User < ActiveRecord::Base
    has_bitmask_attributes :notifications do |config|
      config.attribute :weekly_newsletter,    0b0001
      config.attribute :monthly_newsletter,   0b0010, true
      config.method_format 'send_%s'
    end
  end

After

  # in app/models/user.rb
  class User < ActiveRecord::Base
    has_bitmask_attributes :notifications do |config|
      config.attribute :send_weekly_newsletter,    0b0001
      config.attribute :send_monthly_newsletter,   0b0010, true
    end
  end

Copyright (c) 2012 Amiel Martin, released under the MIT license