Module: ScopedSearch::ClassMethods
- Defined in:
- lib/scoped_search.rb
Class Method Summary collapse
-
.extended(base) ⇒ Object
:nodoc:.
Instance Method Summary collapse
-
#build_scoped_search_conditions(search_string) ⇒ Object
Build a hash that is used for the named_scope search_for.
-
#searchable_on(*fields) ⇒ Object
Creates a named scope in the class it was called upon.
Class Method Details
.extended(base) ⇒ Object
:nodoc:
5 6 7 8 9 |
# File 'lib/scoped_search.rb', line 5 def self.extended(base) # :nodoc: require 'scoped_search/reg_tokens' require 'scoped_search/query_language_parser' require 'scoped_search/query_conditions_builder' end |
Instance Method Details
#build_scoped_search_conditions(search_string) ⇒ Object
Build a hash that is used for the named_scope search_for. This function will split the search_string into keywords, and search for all the keywords in the fields that were provided to searchable_on.
- search_string
-
The search string to parse.
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/scoped_search.rb', line 75 def build_scoped_search_conditions(search_string) if search_string.nil? || search_string.strip.blank? return {:conditions => nil} else query_fields = {} self.scoped_search_fields.each do |field| field_name = connection.quote_table_name(table_name) + "." + connection.quote_column_name(field) query_fields[field_name] = self.columns_hash[field.to_s].type end assoc_model_indx = 0 assoc_fields_indx = 1 assoc_models_to_include = [] self.scoped_search_assoc_groupings.each do |group| assoc_models_to_include << group[assoc_model_indx] group[assoc_fields_indx].each do |group_field| field_name = connection.quote_table_name(group[assoc_model_indx].to_s.pluralize) + "." + connection.quote_column_name(group_field) query_fields[field_name] = self.reflections[group[assoc_model_indx]].klass.columns_hash[group_field.to_s].type end end search_conditions = QueryLanguageParser.parse(search_string) conditions = QueryConditionsBuilder.build_query(search_conditions, query_fields) retVal = {:conditions => conditions} retVal[:include] = assoc_models_to_include unless assoc_models_to_include.empty? return retVal end end |
#searchable_on(*fields) ⇒ Object
Creates a named scope in the class it was called upon.
- fields
-
The fields to search on.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/scoped_search.rb', line 14 def searchable_on(*fields) # Make sure that the table to be searched actually exists if self.table_exists? # Get a collection of fields to be searched on. if fields.first.class.to_s == 'Hash' if fields.first.has_key?(:only) # only search on these fields. fields = fields.first[:only] elsif fields.first.has_key?(:except) # Get all the fields and remove any that are in the -except- list. fields = self.column_names.collect { |column| fields.first[:except].include?(column.to_sym) ? nil : column.to_sym }.compact end end # Get an array of associate modules. assoc_models = self.reflections.collect { |key,value| key } # Subtract out the fields to be searched on that are part of *this* model. # Any thing left will be associate module fields to be searched on. assoc_fields = fields - self.column_names.collect { |column| column.to_sym } # Subtraced out the associated fields from the fields so that you are only left # with fields in *this* model. fields -= assoc_fields # Loop through each of the associate models and group accordingly each # associate model field to search. Assuming the following relations: # has_many :clients # has_many :notes, # belongs_to :user_type # assoc_groupings will look like # assoc_groupings = {:clients => [:first_name, :last_name], # :notes => [:descr], # :user_type => [:identifier]} assoc_groupings = {} assoc_models.each do |assoc_model| assoc_groupings[assoc_model] = [] assoc_fields.each do |assoc_field| unless assoc_field.to_s.match(/^#{assoc_model.to_s}_/).nil? assoc_groupings[assoc_model] << assoc_field.to_s.sub(/^#{assoc_model.to_s}_/, '').to_sym end end end # If a grouping does not contain any fields to be searched on then remove it. assoc_groupings = assoc_groupings.delete_if {|group, field_group| field_group.empty?} # Set the appropriate class attributes. self.cattr_accessor :scoped_search_fields, :scoped_search_assoc_groupings self.scoped_search_fields = fields self.scoped_search_assoc_groupings = assoc_groupings self.named_scope :search_for, lambda { |keywords| self.build_scoped_search_conditions(keywords) } end end |