Module: HasManyBooleans::ClassMethods

Defined in:
lib/has_many_booleans.rb

Instance Method Summary collapse

Instance Method Details

#booleans_defaultObject

:nodoc:



122
123
124
# File 'lib/has_many_booleans.rb', line 122

def booleans_default #:nodoc:
  @booleans_default
end

#booleans_optionsObject

getters



118
119
120
# File 'lib/has_many_booleans.rb', line 118

def booleans_options #:nodoc:
  @booleans_options
end

#booleans_validatorsObject

:nodoc:



126
127
128
# File 'lib/has_many_booleans.rb', line 126

def booleans_validators #:nodoc:
  @booleans_validators
end

#has_many_booleans(*params) ⇒ Object Also known as: hmb

Setup the booleans for a model

The method takes the symbols of the desired booleans as parameters. As last parameter you can apply an options hash. Each symbol represents an index, depending on the position in the list, starting with 1.

class Model < ActiveRecord::Base
  has_many_booleans :name, :password,
    :true => [      :name ],
    :append => 'set',
end

Another way of setting up the booleans is with an hash. This is useful when you want to choose the indexes yourself.

class Model < ActiveRecord::Base
  has_many_booleans({:name => 23, :password => 99},
    :append => 'set')
end

Available options

:true

Takes an array of boolean names which shall default to true.

:append

The name to append to the listed booleans. The underscore is added automatically. nil is also possible. Default is activated.

:field

The database field used. Defaults to booleans.

:suffixes

Specifies, which “alias” methods are created. Defaults to ["?", "=", "!"]. You cannot add new ones, you can only forbid some of them.

:false_values

All the values in the array can be used to set a boolean to false (when used with the = method). Example: Set this to ["0"] and then call some_boolean_activated = "0", it will set the boolean to false. By default, this is set to ActiveRecord::ConnectionAdapters::Column::FALSE_VALUES.

:true_values

Which values should be true (if :unkown_value is set to false) Default is ActiveRecord::ConnectionAdapters::Column::TRUE_VALUES.

:unkown_value

What should be the value of a boolean, if it is not found in the :false_ or :true_values? Default is true, set this to false to get ActiveRecord behaviour.

:lazy

When the :lazy option is set to false, the bitset integer gets changed every time you assign a new value for a boolean. The default setting is true, which means, the integer gets only updated when the object is saved.

:self

This is just another virtual boolean. You can freely assign the name. It is always stored as first bit in the bitset integer (so if the bitset integer is odd, this special boolean is set). You can also set this to true, which means, the :append value is used as method name. Default: false.

:self_value

The default value for the special :self boolean above.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/has_many_booleans.rb', line 37

def has_many_booleans(*params)

  # get params
  if params.last.is_a? Hash # booleans_options
    parse_booleans_options params.pop

    if params.empty?
      warn "has_many_booleans: You applied a single hash as parameter, which gets interpreted as option hash. If you wish to use it as boolean hash, give a {} as second parameter!"
    end
  else
    parse_booleans_options Hash.new
  end

  if params.first.is_a? Hash # alternative usage with a hash instead of array
    params = params.first
    iter_method = :each
  else
    iter_method = :each_with_index
  end

  # data structure: { string => [index, boolean_value] }
  @booleans_default = {}
  params.send(iter_method){ |key, index|
    index = index.to_i+1
    @booleans_default[key.to_s] = [ index,
      @booleans_options[:true].include?(key.to_sym) ||
      @booleans_options[:true].include?(key.to_s)
    ] if index > 0
  }

  # validators
  @booleans_validators = { true => [], false => [] }

  send :include, InstanceMethods

  # hook in callbacks part 1 (to not overwrite after_initialize)
  class << self
    def instantiate_with_booleans(record) #:nodoc:
        object = instantiate_without_booleans record
        object.initialize_booleans
        object
    end
    alias_method_chain :instantiate, :booleans
  end

  before_save :save_booleans

  # register scopes
  booleans_scope = lambda{ |true_or_false, *args|
    indexes = if args.blank?
       [1] # special self boolean
    else
      args.map{ |name|
        if name == nil # allow self in "or" connection
          1
        else
          name = name.to_s
          if !@booleans_default[name]
            warn 'has_many_booleans: You are using unknown boolean names in your scope!'
          else
            2 ** @booleans_default[name][0]
          end
        end
      }.compact
    end
    cond = ["#{@booleans_options[:field]} & ?#{true_or_false ? ' > 0' : ' < 1'}"]*indexes.size*' or '
    where cond, *indexes
   }

  scope :true, lambda { |*args|
    booleans_scope[true, *args]
  }

  scope :false, lambda { |*args|
    booleans_scope[false, *args]
  }
end

#validates_false(*bools) ⇒ Object

List all booleans that are required to be false!

validates_false :description, :password


132
133
134
135
# File 'lib/has_many_booleans.rb', line 132

def validates_false(*bools)
  booleans_validators[false] = bools
  validate :validator_false
end

#validates_true(*bools) ⇒ Object

List all booleans that are required to be true!

validates_false :description, :password


139
140
141
142
# File 'lib/has_many_booleans.rb', line 139

def validates_true(*bools)
  booleans_validators[true] = bools
  validate :validator_true
end