# Tog::Search provides a simple interface to site-wide searches through a flexible collection of +sources+ # that the developer can extend to plug its own classes on the general search. # # ==== Simple example # # Tog::Search.sources << "User" # @results = Tog::Search.search("joe-theplumber") # the @results instance will be paginated # # The modules used as +sources+ should implement a class method called site_search(query, options={}) and # should return an +Array+ instance. module Search # The sources availables to search in. These sources must be strings representing classes o modules that can # be retrieved through
source.constantize
. def self.sources @sources ||= [] end # This method iterates all the classes/modules (usually activerecord models) added to the +sources+ attribute. # For each class, its search method is called and the matches are added to the paginated collection of # final results. # # ==== Attributes # # * :options - search options. # * :paginate_options - The same options allowed for the +paginate+ method provided by will_paginate # # == Filter conditions # # Search may be limited to specific sources by declaring the sources to # include or exclude. Both options accept single sources # (:only => "Model1") or arrays of sources # (:except => ["Model1", "Model2"]). # # Tog::Search.search(term, :only => ["User","Course"]) # Tog::Search.search(term, :except => "ClubHouse") def self.search(query, options = {}, paginate_options = {}) paginate_options.reverse_merge! :per_page => Tog::Config['plugins.tog_core.pagination_size'] results = [] sources.uniq.flatten.each{|name| begin source = name.constantize if source.respond_to?(:site_search) if included_in_search?(name, options) results << source.site_search(query, options) end else RAILS_DEFAULT_LOGGER.warn(<<-WARNING ************************************************************************************************************************************************** SEARCH WARNING: The source #{source} should implement a ´self.site_search(query, options={})´ method to be available on site-wide searches. ************************************************************************************************************************************************** WARNING ) end rescue NameError => e RAILS_DEFAULT_LOGGER.error(<<-ERROR ************************************************************************************************************************************************** SEARCH ERROR: The source #{name} can't be constantized. Double-check it and make sure there is a matching Class or Module. ************************************************************************************************************************************************** ERROR ) end } results.flatten.paginate(paginate_options) end protected def self.included_in_search?(source, options) if options[:only] options[:only].include?(source) elsif options[:except] !options[:except].include?(source) else true end end end