Skip to content

Instantly share code, notes, and snippets.

@TheEmpty
Created March 8, 2012 20:51
Show Gist options
  • Save TheEmpty/2003364 to your computer and use it in GitHub Desktop.
Save TheEmpty/2003364 to your computer and use it in GitHub Desktop.
Bit Mask Helper for ActiveRecord
module QualificationMask
def bitmask_field_for(field, options)
array = options.delete(:with).to_s
field = field.to_s
methods = field.gsub /_mask/, ''
class_eval %(
def #{methods}=(#{methods})
#{methods} = [#{methods}] if not #{methods}.is_a?(Array)
self.#{field} = (#{methods} & #{array}).map { |r| 2**#{array}.index(r) }.sum
end
def #{methods}
list = #{array}.reject { |r| ((self.#{field} || 0) & 2**#{array}.index(r)).zero? }
end
scope :with_#{methods}, lambda { |r|
r = [r] if not r.is_a?(Array)
conditions = []
r.each do |f|
conditions.push("\#{field} & \#{2**#{array}.index(f)} > 0")
end
{
:conditions => conditions.join(' and ')
}
}
)
end
end
class User < ActiveRecord::Base
extend QualificationMask
QUALIFICATIONS = ['ALS', 'Medic', 'First Responder']
bitmask_field_for :qualifications_mask, :with => 'QUALIFICATIONS'
end
user = User.new
user.qualifications = User::QUALIFICATIONS
user.qualifications # => ['ALS', 'Medic', 'First Responder']
user.with_qualifications('ALS').count # => 1
user.with_qualifications(['ALS', 'Medic']).count # => 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment