lib/tableficate/finder.rb in tableficate-0.2.1 vs lib/tableficate/finder.rb in tableficate-0.3.0
- old
+ new
@@ -3,46 +3,78 @@
def tableficate(params)
scope = @scope || self
raise Tableficate::MissingScope unless scope.new.kind_of?(ActiveRecord::Base)
# filtering
- if params
- if params[:filter]
- params[:filter].each do |name, value|
- next if value.blank? or (value.is_a?(Hash) and value.all?{|key, value| value.blank?})
+ if params and params[:filter]
+ params[:filter].each do |name, value|
+ next if value.blank? or (value.is_a?(Hash) and value.all?{|key, value| value.blank?})
- name = name.to_sym
- value.strip! if value.is_a?(String)
+ # cleanup filter params
+ name = name.to_sym
+ if value.is_a?(Array)
+ value.map!{|v| prepare_value(v)}
+ elsif value.is_a?(Hash)
+ value.each do |k, v|
+ value[k] = prepare_value(v)
+ end
+ else
+ value = prepare_value(value)
+ end
- if @filter and @filter[name]
- if @filter[name].is_a?(Proc)
- scope = @filter[name].call(value, scope)
- elsif value.is_a?(String)
- value = "%#{value}%" if @filter[name][:match] == 'contains'
+ # convert dates, datetimes, and timestamps to Ruby objects and account for date filtering on datetime type columns
+ case Tableficate::Utils::find_column_type(scope, name)
+ when :date
+ value = value.to_date
+ when :datetime, :timestamp
+ if value.is_a?(Hash)
+ # if it looks like it's only dates
+ if value[:start].gsub(/\D/, '').length <= 8 and value[:stop].gsub(/\D/, '').length <= 8
+ value = {start: Time.zone.parse(value[:start]), stop: Time.zone.parse(value[:stop]).advance(hours: 23, minutes: 59, seconds: 59)}
+ else
+ value[:start] = Time.zone.parse(value[:start])
+ value[:stop] = Time.zone.parse(value[:stop])
+ end
+ elsif value.is_a?(String)
+ # if it looks like it's only a date
+ if value.gsub(/\D/, '').length <= 8
+ value = Time.zone.parse(value)
+ value = {start: value, stop: value.advance(hours: 23, minutes: 59, seconds: 59)}
+ else
+ value = Time.zone.parse(value)
+ end
+ end
+ end
- scope = scope.where(["#{get_full_column_name(@filter[name][:field])} LIKE ?", value])
- elsif value.is_a?(Array)
- full_column_name = get_full_column_name(@filter[name][:field])
+ # attach the filter
+ if @filter and @filter[name]
+ if @filter[name].is_a?(Proc)
+ scope = @filter[name].call(value, scope)
+ elsif value.is_a?(Array)
+ full_column_name = get_full_column_name(@filter[name][:field])
- if @filter[name][:match] == 'contains'
- scope = scope.where([
- Array.new(value.size, "#{full_column_name} LIKE ?").join(' OR '),
- *value.map{|v| "%#{v}%"}
- ])
- else
- scope = scope.where(["#{full_column_name} IN(?)", value])
- end
- elsif value.is_a?(Hash)
- scope = scope.where(["#{get_full_column_name(@filter[name][:field])} BETWEEN :start AND :stop", value])
+ if @filter[name][:match] == 'contains'
+ scope = scope.where([
+ Array.new(value.size, "#{full_column_name} LIKE ?").join(' OR '),
+ *value.map{|v| "%#{v}%"}
+ ])
+ else
+ scope = scope.where(["#{full_column_name} IN(?)", value])
end
- elsif value.is_a?(Array)
- scope = scope.where(["#{get_full_column_name(name.to_s.gsub(/\W/, ''))} IN(?)", value])
elsif value.is_a?(Hash)
- scope = scope.where(["#{get_full_column_name(name.to_s.gsub(/\W/, ''))} BETWEEN :start AND :stop", value])
+ scope = scope.where(["#{get_full_column_name(@filter[name][:field])} BETWEEN :start AND :stop", value])
else
- scope = scope.where(["#{get_full_column_name(name.to_s.gsub(/\W/, ''))} LIKE ?", value])
+ value = "%#{value}%" if @filter[name][:match] == 'contains'
+
+ scope = scope.where(["#{get_full_column_name(@filter[name][:field])} LIKE ?", value])
end
+ elsif value.is_a?(Array)
+ scope = scope.where(["#{get_full_column_name(name.to_s.gsub(/\W/, ''))} IN(?)", value])
+ elsif value.is_a?(Hash)
+ scope = scope.where(["#{get_full_column_name(name.to_s.gsub(/\W/, ''))} BETWEEN :start AND :stop", value])
+ else
+ scope = scope.where(["#{get_full_column_name(name.to_s.gsub(/\W/, ''))} LIKE ?", value])
end
end
end
# sorting
@@ -59,10 +91,12 @@
if column.present?
sorting[:column] = column.to_sym
sorting[:dir] = ['asc', 'desc'].include?(dir) ? dir : 'asc'
end
scope.tableficate_add_data(:current_sort, sorting)
+ filters_with_field = @filter ? @filter.select{|name, options| not options.is_a?(Proc) and options and options.has_key?(:field)} : {}
+ scope.tableficate_add_data(:field_map, Hash[filters_with_field.map{|name, options| [name, options[:field]]}])
scope
end
def get_full_column_name(name)
name = name.to_s
@@ -73,7 +107,15 @@
else
name
end
end
private :get_full_column_name
+
+ def prepare_value(value)
+ value.strip! if value.respond_to?(:strip!)
+ value = true if value == 'true'
+ value = false if value == 'false'
+ value
+ end
+ private :prepare_value
end
end