module KellyLSB::BitSwitch::ClassMethods
Public Instance Methods
bitswitch(column, hash = {})
click to toggle source
Generate switch methods
# File lib/bitswitch.rb, line 237 def bitswitch(column, hash = {}) # Set column method name columne = column.to_s + '=' # Instance methods send(:include, Module.new { # BitSwitch access method send(:define_method, column) do |*args| val = read_attribute(column) # If nil make 0 val = 0 if val.nil? # Make sure the column value is a Fixnum unless val.is_a?(Fixnum) raise KellyLSB::BitSwitch::Error, "Column: #{column} is not an integer!" end # Convert the Fixnum to a BitSwitch val = val.to_switch hash # Return the value of a specific key if requested return val[args.first] unless args[0].nil? # Return the switch val end # BitSwitch set method send(:define_method, columne) do |args| val = read_attribute(column) # If nil make 0 val = 0 if val.nil? # Get the input data if args.is_a?(Array) input = args[0] truncate = args[1] else input = args truncate = false end # Make sure the value is an integer unless val.is_a?(Fixnum) raise KellyLSB::BitSwitch::Error, "Column: #{column} is not an integer!" end # Make sure the first input is a hash unless input.is_a?(Hash) raise KellyLSB::BitSwitch::Error, "Input: We are expecting at least one argument that is a Hash" end # Convert Fixnum -> BitSwitch -> Hash val = val.to_switch(hash).to_hash # Convert all keys to symbols input.delete_if do |key, val| if key.is_a?(String) input[key.to_sym] = val true else false end end # If we are requested to truncate other keys if truncate == true # Get list of unset keys and set them to false remove = val.keys.collect(&:to_sym) - input.keys.collect(&:to_sym) remove.each { |key| input[key] = false } end # Merge in the changes then convert to BitSwitch val = val.merge(input).to_switch(hash) # Dont save if this is a new model return false if new_record? # Write the updated value update_column(column, val.to_i) # Return the switch return self.send(column) end }) # Scoping methods send(:extend, Module.new { send(:define_method, column) do |*args| # Require at least one argument if args.empty? raise KellyLSB::BitSwitch::Error, "Missing arguments! We were expecing at least one label or bit to query by." end # Invert the label hash bits = hash.invert # Type of condition if args.first.is_a?(String) && ['AND', 'OR'].include?(args.first.to_s.upcase) delimiter = args.shift else delimiter = 'AND' end # Empty conditions conditions = Array.new # Build conditions if args.first.is_a?(Hash) args.first.each do |slug, tf| bit = bits[slug.to_s] conditions << "POW(2, #{bit}) & #{self.table_name}.#{column}" + (tf ? ' > 0' : ' <= 0') end else args.each do |slug| bit = bits[slug.to_s] conditions << "POW(2, #{bit}) & #{self.table_name}.#{column} > 0" end end # If we have query conditions go ahead and return the updated scope return self.where(conditions.join(" #{delimiter} ")) unless conditions.empty? # Return self self end send(:define_method, "#{column}_labels") do |*args| hash.values end }) end