Module: SearchMagic::FullTextSearch::ClassMethods
- Defined in:
- lib/search_magic/full_text_search.rb
Instance Method Summary collapse
- #arrange(arrangeable, direction = :asc) ⇒ Object
- #inverse_searchables ⇒ Object
-
#search_for(pattern) ⇒ Object
(also: #and_for)
To support range searches, this will need to become more complicated.
- #search_on(field_name, options = {}) ⇒ Object
- #searchables ⇒ Object
- #strip_option_terms_from(pattern) ⇒ Object
- #terms_for(pattern) ⇒ Object
Instance Method Details
#arrange(arrangeable, direction = :asc) ⇒ Object
46 47 48 |
# File 'lib/search_magic/full_text_search.rb', line 46 def arrange(arrangeable, direction = :asc) arrangeable.blank? || !searchables.keys.include?(arrangeable.to_sym) ? criteria : order_by([["arrangeable_values.#{arrangeable}", direction]]) end |
#inverse_searchables ⇒ Object
24 25 26 27 28 29 |
# File 'lib/search_magic/full_text_search.rb', line 24 def inverse_searchables @inverse_searchables ||= relations.values. map {|| [, .class_name.constantize] }. select {|, klass| klass < SearchMagic::FullTextSearch && klass.searchable_fields.keys.include?(.inverse_setter.chomp("=").to_sym)}. map(&:first).map(&:name) end |
#search_for(pattern) ⇒ Object Also known as: and_for
To support range searches, this will need to become more complicated. Specifically, it will need to be able to remove any term which contains a [:below, :before, :above, :after] selector, retreive the base selector and the target valuee, and match the latter against the former within the :arrangeable_values array as part of the returned criteria. How this then translates to :values_matching is currently unknown.
35 36 37 38 39 40 41 42 43 |
# File 'lib/search_magic/full_text_search.rb', line 35 def search_for(pattern) , pattern = strip_option_terms_from(pattern) terms = terms_for(pattern) unless terms.blank? send( :"#{[:mode] || default_search_mode}_in", :searchable_values => terms) else criteria end end |
#search_on(field_name, options = {}) ⇒ Object
16 17 18 |
# File 'lib/search_magic/full_text_search.rb', line 16 def search_on(field_name, = {}) searchable_fields[field_name] = end |
#searchables ⇒ Object
20 21 22 |
# File 'lib/search_magic/full_text_search.rb', line 20 def searchables @searchables ||= create_searchables end |
#strip_option_terms_from(pattern) ⇒ Object
50 51 52 53 54 55 56 |
# File 'lib/search_magic/full_text_search.rb', line 50 def strip_option_terms_from(pattern) unless pattern.blank? [Hash[*(pattern.scan(option_terms).flatten)].symbolize_keys, pattern.gsub(option_terms, '').strip] else [{}, pattern] end end |
#terms_for(pattern) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/search_magic/full_text_search.rb', line 58 def terms_for(pattern) rval = /("[^"]+"|'[^']+'|\S+)/ rnot_separator = "[^#{separator}]+" rsearch = /(?:(#{searchable_names})(?:#{separator}#{rval}|(#{presence_detector_escaped})))|#{rval}/i unless pattern.blank? terms = pattern.scan(rsearch).map(&:compact).map do |term| selector = term.length > 1 ? Regexp.escape(term.first) : rnot_separator = searchables[term.first.match(/^[^:]+/)[0].to_sym] if term.length > 1 parsed_date = Chronic.parse(term.last) if && .datable? prefix = "#{selector}#{separator}" prefix = "(#{prefix})?" if term.length == 1 fragment = /^#{selector}#{separator}#{parsed_date}/i if parsed_date fragment = /^#{prefix}[^#{separator}\s]+/i if term.last == presence_detector fragment || term.last.scan(/\b(\S+)\b/).flatten.map do |word| /^#{prefix}.*#{Regexp.escape(word)}/i end end.flatten else [] end end |