Skip to content
n Booleans = 1 Integer, saves columns and migrations.
Pull request Compare This branch is 78 commits behind grosser:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
benchmark
lib
spec
Rakefile
Readme.md
VERSION
bitfields.gemspec

Readme.md

Save migrations and columns by storing multiple booleans in a single integer.
e.g. true-false-false = 1, false-true-false = 2, true-false-true = 5 (1,2,4,8,..)

class User < ActiveRecord::Base
  include Bitfields
  bitfield :my_bits, 1 => :seller, 2 => :insane, 4 => :stupid
end

user = User.new(:seller => true, :insane => true)
user.seller == true
user.stupid? == false
user.my_bits == 3
  • records changes user.chamges == {:seller => [false, true]}
  • adds scopes User.seller.stupid.first (deactivate with bitfield ..., :scopes => false)
  • builds sql User.bitfield_sql(:insane => true, :stupid => false) == '(users.my_bits & 3) = 1'
  • builds index-using sql with bitfield ... ,:query_mode => :in_list and User.bitfield_sql(:insane => true, :stupid => false) == 'users.my_bits IN (2, 3)' (2 and 1+2), often slower than :bit_operator sql especially for high number of bits
  • builds update sql User.set_bitfield_sql(:insane => true, :stupid => false) == 'my_bits = (my_bits | 6) - 4'
  • faster sql than any other bitfield lib through combination of multiple bits into a single sql statement
  • gives access to bits User.bitfields[:my_bits][:stupid] == 4

Install

As Gem: sudo gem install bitfields
Or as Rails plugin: rails plugin install git://github.com/grosser/bitfields.git

Migration

ALWAYS set a default, bitfield queries will not work for NULL t.integer :my_bits, :default => 0, :null => false OR add_column :users, :my_bits, :integer, :default => 0, :null => false

Examples

Update all users User.seller.not_stupid.update_all(User.set_bitfield_sql(:seller => true, :insane => true))

Delete the shop when a user is no longer a seller before_save :delete_shop, :if => lambda{|u| u.changes['seller'] == [true, false]}

TIPS

  • Never do: "#{bitfield_sql(...)} AND #{bitfield_sql(...)}", merge both into one hash
  • bit_operator is faster in most cases, use :query_mode => :in_list sparingly
  • Standard mysql integer is 4 byte -> 32 bitfields
  • If you are lazy or bad at math you can also do bitfields :bits, :foo, :bar, :baz

performance

TODO

  • convenient named scope User.with_bitfields(:xxx=>true, :yy=>false)

Authors

Contributors

Michael Grosser
michael@grosser.it
Hereby placed under public domain, do what you want, just do not hold me accountable...

Something went wrong with that request. Please try again.