Class ScopedSearch::Definition
In: lib/scoped_search/definition.rb
Parent: Object

The ScopedSearch definition class defines on what fields should be search in the model in what cases

A definition can be created by calling the scoped_search method on an ActiveRecord-based class, so you should not create an instance of this class yourself.

Methods

Classes and Modules

Class ScopedSearch::Definition::Field

Constants

NUMERICAL_REGXP = /^\-?\d+(\.\d+)?$/
INTEGER_REGXP = /^\-?\d+$/

Attributes

default_order  [RW] 
klass  [R] 
profile  [RW] 

Public Class methods

Initializes a ScopedSearch definition instance. This method will also setup a database adapter and create the :search_for named scope if it does not yet exist.

[Source]

     # File lib/scoped_search/definition.rb, line 149
149:     def initialize(klass)
150:       @klass                 = klass
151:       @fields                = {}
152:       @unique_fields         = []
153:       @profile_fields        = {:default => {}}
154:       @profile_unique_fields = {:default => []}
155: 
156: 
157:       register_named_scope! unless klass.respond_to?(:search_for)
158:       register_complete_for! unless klass.respond_to?(:complete_for)
159: 
160:     end

Protected Class methods

[Source]

     # File lib/scoped_search/definition.rb, line 264
264:         def self.complete_for(query, options = {})
265:           ScopedSearch::AutoCompleteBuilder.auto_complete(@scoped_search , query, options)
266:         end

Public Instance methods

Returns a list of fields that should be searched on by default.

Every field will show up in this method‘s result, except for fields for which the only_explicit parameter is set to true.

[Source]

     # File lib/scoped_search/definition.rb, line 226
226:     def default_fields
227:       unique_fields.reject { |field| field.only_explicit }
228:     end

Returns a list of appropriate fields to search in given a search keyword and operator.

[Source]

     # File lib/scoped_search/definition.rb, line 200
200:     def default_fields_for(value, operator = nil)
201: 
202:       column_types  = []
203:       column_types += [:string, :text]                      if [nil, :like, :unlike, :ne, :eq].include?(operator)
204:       column_types += [:double, :float, :decimal] if value =~ NUMERICAL_REGXP
205:       column_types += [:integer] if value =~ INTEGER_REGXP
206:       column_types += [:datetime, :date, :timestamp]        if (parse_temporal(value))
207: 
208:       default_fields.select { |field| column_types.include?(field.type) && !field.set? }
209:     end

Defines a new search field for this search definition.

[Source]

     # File lib/scoped_search/definition.rb, line 231
231:     def define(options)
232:       Field.new(self, options)
233:     end

this method return definitions::field object from string

[Source]

     # File lib/scoped_search/definition.rb, line 175
175:     def field_by_name(name)
176:       field = fields[name.to_sym] unless name.blank?
177:       if field.nil?
178:         dotted = name.to_s.split('.')[0]
179:         field = fields[dotted.to_sym] unless dotted.nil?
180:       end
181:       field
182:     end

[Source]

     # File lib/scoped_search/definition.rb, line 164
164:     def fields
165:       @profile ||= :default
166:       @profile_fields[@profile] ||= {}
167:     end

this method is used by the syntax auto completer to suggest operators.

[Source]

     # File lib/scoped_search/definition.rb, line 185
185:     def operator_by_field_name(name)
186:       field = field_by_name(name)
187:       return [] if field.nil?
188:       return field.operators                                   if field.operators
189:       return ['= ', '!= ']                                     if field.set?
190:       return ['= ', '> ', '< ', '<= ', '>= ','!= ', '^ ', '!^ '] if field.numerical?
191:       return ['= ', '!= ', '~ ', '!~ ', '^ ', '!^ ']             if field.textual?
192:       return ['= ', '> ', '< ']                                if field.temporal?
193:       raise ScopedSearch::QueryNotSupported, "could not verify '#{name}' type, this can be a result of a definition error"
194:     end

Try to parse a string as a datetime. Supported formats are Today, Yesterday, Sunday, ‘1 day ago’, ‘2 hours ago’, ‘3 months ago’,’Jan 23, 2004’ And many more formats that are documented in Ruby DateTime API Doc.

[Source]

     # File lib/scoped_search/definition.rb, line 214
214:     def parse_temporal(value)
215:       return Date.current if value =~ /\btoday\b/i
216:       return 1.day.ago.to_date if value =~ /\byesterday\b/i
217:       return (eval(value.strip.gsub(/\s+/,'.').downcase)).to_datetime if value =~ /\A\s*\d+\s+\bhours?|minutes?\b\s+\bago\b\s*\z/i
218:       return (eval(value.strip.gsub(/\s+/,'.').downcase)).to_date if value =~ /\A\s*\d+\s+\b(days?|weeks?|months?|years?)\b\s+\bago\b\s*\z/i
219:       DateTime.parse(value, true) rescue nil
220:     end

[Source]

     # File lib/scoped_search/definition.rb, line 169
169:     def unique_fields
170:       @profile ||= :default
171:       @profile_unique_fields[@profile] ||= []
172:     end

Protected Instance methods

Registers the complete_for method within the class that is used for searching.

[Source]

     # File lib/scoped_search/definition.rb, line 262
262:     def register_complete_for! # :nodoc
263:       @klass.class_eval do
264:         def self.complete_for(query, options = {})
265:           ScopedSearch::AutoCompleteBuilder.auto_complete(@scoped_search , query, options)
266:         end
267:       end
268:     end

Registers the search_for named scope within the class that is used for searching.

[Source]

     # File lib/scoped_search/definition.rb, line 238
238:     def register_named_scope! # :nodoc
239:       if @klass.ancestors.include?(ActiveRecord::Base)
240:         case ActiveRecord::VERSION::MAJOR
241:         when 2
242:           @klass.named_scope(:search_for, lambda { |*args| ScopedSearch::QueryBuilder.build_query(self, args[0], args[1]) })
243:         when 3
244:           @klass.scope(:search_for, lambda { |*args|
245:             find_options = ScopedSearch::QueryBuilder.build_query(self, args[0], args[1])
246:             search_scope = @klass.scoped
247:             search_scope = search_scope.where(find_options[:conditions]) if find_options[:conditions]
248:             search_scope = search_scope.includes(find_options[:include]) if find_options[:include]
249:             search_scope = search_scope.joins(find_options[:joins]) if find_options[:joins]
250:             search_scope = search_scope.reorder(find_options[:order]) if find_options[:order]
251:             search_scope
252:           })
253:         else
254:           raise "This ActiveRecord version is currently not supported!"
255:         end
256:       else
257:         raise "Currently, only ActiveRecord 2.1 or higher is supported!"
258:       end
259:     end

[Validate]