module Mongoid::StateBits::ClassMethods

Public Instance Methods

state_bits(params) click to toggle source
# File lib/mongoid/state_bits.rb, line 20
def state_bits(params)
  if params.is_a? Array
    bits = params
    default = 0
  elsif params.is_a? Hash
    bits = params.keys
    default = bits.each_with_index.inject(0){|sum, vi| sum + (params[vi[0]] ? 2**vi[1] : 0)}
  else
    raise "Invalid state_bits params: should be Array or Hash"
  end
  # declare the field
  field :state_bits, type: Integer, default: default
  
  scope :state, ->(map){
    keys = bits.map{|k| k.to_sym}
    select, filter = 0, 0
    map.each_pair do |key, value|
      v = 2**keys.index(key)
      select += v
      filter += (value ? v : 0)
    end
    where("this.state_bits & #{select} == #{filter}")
  }
  
  # define methods
  bits.each_with_index do |bit, index|
    define_method "#{bit}=" do |bool|
      if ["true", true, "1", 1].include?(bool)
        self.state_bits |= 2**index
      else
        self.state_bits -= (self.state_bits & 2**index)
      end
    end
    define_method bit do
      self.state_bits & 2**index != 0
    end
    alias_method "#{bit}?", "#{bit}"
    # then define scopes
    scope bit, ->{ where("this.state_bits & #{2**index}")}
    scope "non#{bit}", ->{ where("(this.state_bits & #{2**index}) == 0")}
  end
end