Module: HasBitField

Defined in:
lib/has-bit-field.rb

Instance Method Summary collapse

Instance Method Details

#has_bit_field(bit_field_attribute, *args) ⇒ Object

The first arguement bit_field_attribute should be a symbol, the name of attribute that will hold the actual bit field all following arguments should also be symbols, which will be the name of each flag in the bit field



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/has-bit-field.rb', line 6

def has_bit_field(bit_field_attribute, *args)
  args.each_with_index do |field,i|
    class_eval %{
      class << self
        def #{field}_bit
          (1 << #{i})
        end
      end

      def #{field}
        (#{bit_field_attribute} & self.class.#{field}_bit) != 0
      end

      alias #{field}? #{field}

      def #{field}=(v)
        if v.to_s == "true" || v.to_s == "1"
          self.#{bit_field_attribute} = (#{bit_field_attribute} || 0) | self.class.#{field}_bit
        else
          self.#{bit_field_attribute} = (#{bit_field_attribute} || 0) & ~self.class.#{field}_bit
        end
      end

      def #{field}_was
        (#{bit_field_attribute}_was & self.class.#{field}_bit) != 0
      end

      def #{field}_changed?
        #{field} != #{field}_was
      end
    }

    scope_sym = respond_to?(:validates) ? :scope : :named_scope

    if columns_hash[bit_field_attribute.to_s].null
      class_eval %{
        send scope_sym, :#{field}, :conditions => ["#{table_name}.#{bit_field_attribute} IS NOT NULL AND (#{table_name}.#{bit_field_attribute} & ?) != 0", #{field}_bit]
        send scope_sym, :not_#{field}, :conditions => ["#{table_name}.#{bit_field_attribute} IS NULL OR (#{table_name}.#{bit_field_attribute} & ?) = 0", #{field}_bit]          
      }
    else
      class_eval %{
        send scope_sym, :#{field}, :conditions => ["(#{table_name}.#{bit_field_attribute} & ?) != 0", #{field}_bit]
        send scope_sym, :not_#{field}, :conditions => ["(#{table_name}.#{bit_field_attribute} & ?) = 0", #{field}_bit]
      }
    end

  end
end