lib/scoped_search/definition.rb in scoped_search-3.0.1 vs lib/scoped_search/definition.rb in scoped_search-3.1.0
- old
+ new
@@ -57,24 +57,22 @@
end
# The ActiveRecord-based class that belongs to this field.
def klass
@klass ||= if relation
- related = definition.klass.reflections[relation]
- raise ScopedSearch::QueryNotSupported, "relation '#{relation}' not one of #{definition.klass.reflections.keys.join(', ')} " if related.nil?
- related.klass
+ definition.reflection_by_name(definition.klass, relation).klass
else
definition.klass
end
end
# The ActiveRecord-based class that belongs the key field in a key-value pair.
def key_klass
@key_klass ||= if key_relation
- definition.klass.reflections[key_relation].klass
+ definition.reflection_by_name(definition.klass, key_relation).klass
elsif relation
- definition.klass.reflections[relation].klass
+ definition.reflection_by_name(definition.klass, relation).klass
else
definition.klass
end
end
@@ -85,11 +83,11 @@
klass.columns_hash[field.to_s]
else
if "#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}".to_f < 4.1
raise ActiveRecord::UnknownAttributeError, "#{klass.inspect} doesn't have column #{field.inspect}."
else
- raise ActiveRecord::UnknownAttributeError.new( klass, field )
+ raise ActiveRecord::UnknownAttributeError.new(klass, field)
end
end
end
end
@@ -196,11 +194,11 @@
return field.operators if field.operators
return ['= ', '!= '] if field.set?
return ['= ', '> ', '< ', '<= ', '>= ','!= ', '^ ', '!^ '] if field.numerical?
return ['= ', '!= ', '~ ', '!~ ', '^ ', '!^ '] if field.textual?
return ['= ', '> ', '< '] if field.temporal?
- raise ScopedSearch::QueryNotSupported, "could not verify '#{name}' type, this can be a result of a definition error"
+ raise ScopedSearch::QueryNotSupported, "Unsupported type '#{field.type.inspect}')' for field '#{name}'. This can be a result of a search definition problem."
end
NUMERICAL_REGXP = /^\-?\d+(\.\d+)?$/
INTEGER_REGXP = /^\-?\d+$/
@@ -238,43 +236,32 @@
# Defines a new search field for this search definition.
def define(options)
Field.new(self, options)
end
+ # Returns a reflection for a given klass and name
+ def reflection_by_name(klass, name)
+ return if name.nil?
+ klass.reflections[name.to_sym] || klass.reflections[name.to_s]
+ end
+
protected
# Registers the search_for named scope within the class that is used for searching.
def register_named_scope! # :nodoc
definition = self
- if @klass.ancestors.include?(ActiveRecord::Base)
- case ActiveRecord::VERSION::MAJOR
- when 3
- @klass.scope(:search_for, lambda { |*args|
- find_options = ScopedSearch::QueryBuilder.build_query(definition, args[0], args[1])
- search_scope = @klass.scoped
- search_scope = search_scope.where(find_options[:conditions]) if find_options[:conditions]
- search_scope = search_scope.includes(find_options[:include]) if find_options[:include]
- search_scope = search_scope.joins(find_options[:joins]) if find_options[:joins]
- search_scope = search_scope.reorder(find_options[:order]) if find_options[:order]
- search_scope
- })
- when 4
- @klass.scope(:search_for, lambda { |*args|
- find_options = ScopedSearch::QueryBuilder.build_query(definition, args[0], args[1])
- search_scope = @klass
- search_scope = search_scope.where(find_options[:conditions]) if find_options[:conditions]
- search_scope = search_scope.includes(find_options[:include]) if find_options[:include]
- search_scope = search_scope.references(find_options[:include]) if find_options[:include]
- search_scope = search_scope.joins(find_options[:joins]) if find_options[:joins]
- search_scope = search_scope.reorder(find_options[:order]) if find_options[:order]
- search_scope
- })
- else
- raise "This ActiveRecord version is currently not supported!"
- end
- else
- raise "Currently, only ActiveRecord 3 or newer is supported!"
- end
+ @klass.scope(:search_for, proc { |query, options|
+ search_scope = ActiveRecord::VERSION::MAJOR == 3 ? @klass.scoped : @klass
+
+ find_options = ScopedSearch::QueryBuilder.build_query(definition, query || '', options || {})
+ search_scope = search_scope.where(find_options[:conditions]) if find_options[:conditions]
+ search_scope = search_scope.includes(find_options[:include]) if find_options[:include]
+ search_scope = search_scope.joins(find_options[:joins]) if find_options[:joins]
+ search_scope = search_scope.reorder(find_options[:order]) if find_options[:order]
+ search_scope = search_scope.references(find_options[:include]) if find_options[:include] && ActiveRecord::VERSION::MAJOR >= 4
+
+ search_scope
+ })
end
# Registers the complete_for method within the class that is used for searching.
def register_complete_for! # :nodoc
@klass.extend(ScopedSearch::AutoCompleteClassMethods)