Module: BitMagic::Adapters::ActiveRecordAdapter::ClassMethods
- Defined in:
- lib/bit_magic/adapters/active_record_adapter.rb
Constant Summary collapse
- BIT_MAGIC_BOOLEAN_FALSE =
A list of values that are falsy. This is only used as a fallback in case the built-in ActiveRecord boolean cast fails. Taken from ActiveModel::Type::Boolean::FALSE_VALUES with the exception that nil is also treated as false.
[false, 0, '0', 'f', 'F', 'false', 'FALSE', 'off', 'OFF', nil].freeze
- BIT_MAGIC_BOOLEAN_CASTER =
Cast the given value into a Boolean. Follows ActiveRecord::Type::Boolean casting if available, with the addition that nil is treated as false. Will fall back to using the BIT_MAGIC_BOOLEAN_FALSE list above
lambda do |val| if defined?(ActiveRecord::Type::Boolean) caster = ActiveRecord::Type::Boolean.new # Rails 5 and up return !!caster.cast(val) if caster.respond_to?(:cast) end # Fallback, values copied from ActiveRecord::Type::Boolean from Rails 5 # can be found at ActiveRecord::ConnectionAdapters::Column for Rails <=4 !BIT_MAGIC_BOOLEAN_FALSE.include?(val) end
- BIT_MAGIC_ADAPTER_DEFAULTS =
Adapter options specific to this adapter
:named_scopes Enables (true) or disables (false) individual scopes to query fields
:query_by_value whether to use bitwise operations or IN (?) when querying by default will use IN (?) if the total bits defined by bit_magic is less than or equal to 8. true to always query by value, false to always query using bitwise operations
{ :bool_caster => BIT_MAGIC_BOOLEAN_CASTER, :named_scopes => true, :query_by_value => 8 }.freeze
Instance Method Summary collapse
-
#bit_magic_adapter(name) ⇒ Object
This method is called by Base#bit_magic after setting up the magician Here, we inject query helpers, scopes, and other useful methods.
-
#bit_magic_adapter_defaults(options = {}) ⇒ Object
Method used to set adapter defaults as options to Magician, Used by the bit_magic definition to add custom options to the magician.
Instance Method Details
#bit_magic_adapter(name) ⇒ Object
This method is called by Base#bit_magic after setting up the magician Here, we inject query helpers, scopes, and other useful methods
Query helpers: (NAMESPACE is the name given to bit_magic) All the methods that generate where queries take an optional options hash as the last value. Can be used to alter options given to bit_magic. eg: passing ‘false’ as the last argument will force the query to generate bitwise operations instead of ‘IN (?)’ queries
NAMESPACE_query_helper(field_names = nil)
an internal method used by other query helpers
NAMESPACE_where_in(array, column_name = nil)
generates a 'WHERE column_name IN (?)' query for the array numbers
column_name defaults to attribute_name in the options
NAMESPACE_with_all(*field_names, options = {})
takes one or more field names, and queries for values where ALL of
them are enabled. For fields with multiple bits, they must be max value
This is the equivalent of: field[0] and field[1] and field[2] ...
NAMESPACE_with_any(*field_names, options = {})
takes one or more field names, and queries for values where any of
them are enabled.
This is the equivalent of: field[0] or field[1] or field[2] ...
NAMESPACE_without_any(*field_names, options = {})
takes one or more field names, and queries for values where at least
one of them is disabled. For fields with multiple bits, any value
other than maximum number.
This is the equivalent of: !field[0] or !field[1] or !field[2] ...
NAMESPACE_without_all(*field_names, options = {})
takes one or more field names and queries for values where none of
them are enabled (all disabled). For fields with multiple bits,
value must be zero.
This is the equivalent of: !field[0] and !field[1] and !field[2] ...
NAMESPACE_equals(field_value_list, options = {})
* this will truncate values to match the number of bits available
field_value_list is a Hash with field_name => value key-pairs.
generates a query that matches the bits to the value, exactly
This is the equivalent of: field[0] = val and field[1] = value ...
Additional named scopes These can be disabled by passing ‘named_scopes: false’ as an option FIELD is the field name for the bit/bit range
NAMESPACE_FIELD
queries for values where FIELD has been enabled
NAMESPACE_not_FIELD
queries for values where FIELD has been disabled (not enabled)
NAMESPACE_FIELD_equals(value)
* only exists for fields with more than one bit
queries for values where FIELD is exactly equal to value
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/bit_magic/adapters/active_record_adapter.rb', line 139 def bit_magic_adapter(name) query_prep = :"#{name}_query_helper" query_in = :"#{name}_where_in" self.class_eval do # Internal method used by the other queries define_singleton_method(query_prep) do |field_names = nil| magician = @bit_magic_fields[name] bit_gen = magician.bits_generator = (field_names.is_a?(Array) and field_names.last.is_a?(Hash)) ? field_names.pop : {} by_value = .key?(:query_by_value) ? [:query_by_value] : magician.[:query_by_value] by_value = (magician.bits_length <= by_value) if by_value.is_a?(Integer) column_name = [:column_name] || magician.[:column_name] || magician.[:attribute_name] [magician, bit_gen, by_value, column_name] end define_singleton_method(query_in) do |arr, column_name = nil| where("\"#{self.table_name}\".#{column_name} IN (?)", arr) end define_singleton_method(:"#{name}_with_all") do |*field_names| magician, bit_gen, by_value, column_name = self.send(query_prep, field_names) if by_value === true self.send(query_in, bit_gen.all_of(*field_names), column_name) else all_of_num = bit_gen.all_of_number(*field_names) where("(\"#{self.table_name}\".#{column_name} & ?) == ?", all_of_num, all_of_num) end end define_singleton_method(:"#{name}_without_any") do |*field_names| magician, bit_gen, by_value, column_name = self.send(query_prep, field_names) if by_value === true self.send(query_in, bit_gen.instead_of(*field_names), column_name) else bit_num = bit_gen.any_of_number(*field_names) where("(\"#{self.table_name}\".#{column_name} & ?) != ?", bit_num, bit_num) end end define_singleton_method(:"#{name}_without_all") do |*field_names| magician, bit_gen, by_value, column_name = self.send(query_prep, field_names) if by_value === true self.send(query_in, bit_gen.none_of(*field_names), column_name) else where("(\"#{self.table_name}\".#{column_name} & ?) == 0", bit_gen.any_of_number(*field_names)) end end # Query for if any of these bits are set. define_singleton_method(:"#{name}_with_any") do |*field_names| magician, bit_gen, by_value, column_name = self.send(query_prep, field_names) if by_value === true self.send(query_in, bit_gen.any_of(*field_names), column_name) else where("(\"#{self.table_name}\".#{column_name} & ?) > 0", bit_gen.any_of_number(*field_names)) end end define_singleton_method(:"#{name}_equals") do |field_value, = {}| magician, bit_gen, by_value, column_name = self.send(query_prep, []) if by_value === true self.send(query_in, bit_gen.equal_to(field_value), column_name) else all_num, none_num = bit_gen.equal_to_numbers(field_value) where("(\"#{self.table_name}\".#{column_name} & ?) == ? AND (\"#{self.table_name}\".#{column_name} & ?) == 0", all_num, all_num, none_num) end end end if @bit_magic_fields and @bit_magic_fields[name] and @bit_magic_fields[name].[:named_scopes] fields = @bit_magic_fields[name].field_list self.class_eval do fields.each_pair do |field, value| define_singleton_method(:"#{name}_#{field}") do self.send(:"#{name}_with_all", field) end define_singleton_method(:"#{name}_not_#{field}") do self.send(:"#{name}_without_all", field) end if value.is_a?(Array) and value.length > 1 define_singleton_method(:"#{name}_#{field}_equals") do |val| self.send(:"#{name}_equals", field => val) end end end end end end |
#bit_magic_adapter_defaults(options = {}) ⇒ Object
Method used to set adapter defaults as options to Magician, Used by the bit_magic definition to add custom options to the magician
82 83 84 |
# File 'lib/bit_magic/adapters/active_record_adapter.rb', line 82 def bit_magic_adapter_defaults( = {}) BIT_MAGIC_ADAPTER_DEFAULTS.merge() end |