+# Mixin module providing a method to convert filters into a list of SQL
+# fragments suitable to be fed to ActiveRecord #where.
+#
# Expects:
-# @where
-# @filters
-# +model_class+
+# model_class
# Operates on:
# @objects
module RecordFilters
+ # Input:
+ # +filters+ array of conditions, each being [column, operator, operand]
+ # +ar_table_name+ name of SQL table
+ #
+ # Output:
+ # Hash with two keys:
+ # :cond_out array of SQL fragments for each filter expression
+ # :param_out array of values for parameter substitution in cond_out
def record_filters filters, ar_table_name
cond_out = []
param_out = []
raise ArgumentError.new("Invalid attribute '#{attr}' in filter")
end
case operator.downcase
- when '=', '<', '<=', '>', '>=', 'like'
+ when '=', '<', '<=', '>', '>=', '!=', 'like'
if operand.is_a? String
+ if operator == '!='
+ operator = '<>'
+ end
cond_out << "#{ar_table_name}.#{attr} #{operator} ?"
if (# any operator that operates on value rather than
# representation:
param_out << operand
elsif operand.nil? and operator == '='
cond_out << "#{ar_table_name}.#{attr} is null"
+ elsif operand.nil? and operator == '!='
+ cond_out << "#{ar_table_name}.#{attr} is not null"
else
raise ArgumentError.new("Invalid operand type '#{operand.class}' "\
"for '#{operator}' operator in filters")
end
- when 'in'
+ when 'in', 'not in'
if operand.is_a? Array
- cond_out << "#{ar_table_name}.#{attr} IN (?)"
+ cond_out << "#{ar_table_name}.#{attr} #{operator} (?)"
param_out << operand
else
raise ArgumentError.new("Invalid operand type '#{operand.class}' "\