class ActiveRecord::Base
Public Class Methods
assoc_filter_to_sql(attr, filter, negation=false)
click to toggle source
# File lib/active_filtr.rb, line 135 def self.assoc_filter_to_sql(attr, filter, negation=false) if filter.respond_to?(:each) return self.value_combination_to_sql(attr, filter, :assoc) end negation = negation ? 'NOT ' : '' assoc = self.reflect_on_association(attr) if assoc.macro == :has_and_belongs_to_many number_filter = self.number_filter_to_sql(assoc.association_foreign_key, filter) values = number_filter[1..-1] sql = "id #{negation}IN (SELECT #{assoc.foreign_key} FROM #{assoc.join_table} WHERE #{number_filter.first})" end # todo: erweitern return [sql] + values end
boolean_filter_to_sql(attr, filter, negation=false)
click to toggle source
# File lib/active_filtr.rb, line 127 def self.boolean_filter_to_sql(attr, filter, negation=false) if filter.respond_to?(:each) return self.value_combination_to_sql(attr, filter, :boolean) end negation = negation ? 'NOT ' : '' return ["#{negation}#{attr} = ?", filter] end
date_filter_to_sql(attr, filter, negation=false)
click to toggle source
# File lib/active_filtr.rb, line 112 def self.date_filter_to_sql(attr, filter, negation=false) negation = negation ? 'NOT ' : '' if filter.respond_to?(:each) if filter.size != 2 # todo: value_combination einbauen raise "invalid date filter: #{filter.inspect} 2 elements expected, #{filter.size} given" end sql = "#{negation}#{attr} BETWEEN ? AND ?" values = filter else sql = "#{negation}#{attr} = ?" values = [filter] end return [sql] + values end
filter(filter)
click to toggle source
todo: auslagern in eigenes gem
# File lib/active_filtr.rb, line 11 def self.filter(filter) relation = self # self.joins_for_filter(filter).each do |join_table| # relation = relation.joins(join_table) # end return relation.where(*self.filter_to_sql(filter)) end
filter_combination_to_sql(filter)
click to toggle source
# File lib/active_filtr.rb, line 38 def self.filter_combination_to_sql(filter) if [:and, :or].include? filter.first combination = filter.first filter = filter[1..-1] end combination ||= :or sqls = [] values = [] filter.each do |f| f = self.filter_to_sql(f) sqls << f.first values += f[1..-1] end sql = '(' + sqls.join(" #{combination.to_s.upcase} ") + ')' return [sql] + values end
filter_to_sql(filter)
click to toggle source
# File lib/active_filtr.rb, line 29 def self.filter_to_sql(filter) if filter.is_a? Hash # todo result = hash_filter_to_sql(filter) elsif filter.respond_to? :each result = filter_combination_to_sql(filter) end # todo: else return result end
hash_filter_to_sql(filter)
click to toggle source
# File lib/active_filtr.rb, line 55 def self.hash_filter_to_sql(filter) sqls = [] values = [] filter.each do |attr, filter| if self.reflect_on_association(attr) result = self.assoc_filter_to_sql(attr, filter) elsif column = self.columns_hash[attr.to_s] result = case column.type when :string self.string_filter_to_sql(attr, filter) when :integer, :decimal self.number_filter_to_sql(attr, filter) when :date self.date_filter_to_sql(attr, filter) when :boolean self.boolean_filter_to_sql(attr, filter) end # todo: erweitern else raise "Not possible to set a filter for #{attr}" end sqls << result.first values += result[1..-1] end sql = sqls.join(' AND ') return [sql] + values end
joins_for_filter(filter)
click to toggle source
# File lib/active_filtr.rb, line 19 def self.joins_for_filter(filter) join_tables = [] filter.each do |attr, filter| if assoc = self.reflect_on_association(attr) and assoc.macro != :belongs_to join_tables << assoc.plural_name.to_sym # todo end end return join_tables.uniq end
number_filter_to_sql(attr, filter, negation=false)
click to toggle source
# File lib/active_filtr.rb, line 93 def self.number_filter_to_sql(attr, filter, negation=false) negation = negation ? 'NOT ' : '' if filter.respond_to?(:each) return self.value_combination_to_sql(attr, filter, :number) elsif filter.is_a? String unless result = filter.match(/^([!<>=]*)(\d+\.?\d*)$/) raise "invalid number filter: '#{filter}'" end connective = result[1].blank? ? '=' : result[1] value = result[2].include?('.') ? result[2].to_f : result[2].to_i sql = "#{negation}#{attr} #{connective} ?" values = [value] else sql = "#{negation}#{attr} = ?" values = [filter] end return [sql] + values end
string_filter_to_sql(attr, filter, negation=false)
click to toggle source
# File lib/active_filtr.rb, line 83 def self.string_filter_to_sql(attr, filter, negation=false) negation = negation ? 'NOT ' : '' if filter.respond_to?(:each) return self.value_combination_to_sql(attr, filter, :string) else sql = "#{negation}#{attr} = ?" end return [sql, filter] end
value_combination_to_sql(attr, filter, filter_type)
click to toggle source
# File lib/active_filtr.rb, line 149 def self.value_combination_to_sql(attr, filter, filter_type) # todo: check if set is possible if filter.first == :not return self.send("#{filter_type}_filter_to_sql", attr, filter[1], true) elsif [:and, :or].include? filter.first combination = filter.first filter = filter[1..-1] end combination ||= :or sqls = [] values = [] filter.each do |f| f = self.send("#{filter_type}_filter_to_sql", attr, f) sqls << f.first values += f[1..-1] end sql = '(' + sqls.join(" #{combination.to_s.upcase} ") + ')' return [sql] + values end