lib/tanker.rb in tanker-1.1.3 vs lib/tanker.rb in tanker-1.1.4

- old
+ new

@@ -101,22 +101,26 @@ # fetch values from index tank or just the type and id to instace results localy options[:fetch] = "__type,__id" options[:fetch] += ",#{fetch.join(',')}" if fetch options[:snippet] = snippets.join(',') if snippets + # convert category_filters to a json string + options[:category_filters] = options[:category_filters].to_json if options[:category_filters] + search_on_fields = models.map{|model| model.tanker_config.indexes.map{|arr| arr[0]}.uniq}.flatten.uniq.join(":(#{query.to_s}) OR ") - query = "#{search_on_fields}:(#{query.to_s}) OR __any:(#{query.to_s}) __type:(#{models.map(&:name).map {|name| "\"#{name.split('::').join(' ')}\"" }.join(' OR ')})" + query = "(#{search_on_fields}:(#{query.to_s}) OR __any:(#{query.to_s})) __type:(#{models.map(&:name).map {|name| "\"#{name.split('::').join(' ')}\"" }.join(' OR ')})" options = { :start => paginate[:per_page] * (paginate[:page] - 1), :len => paginate[:per_page] }.merge(options) if paginate results = index.search(query, options) + categories = results['facets'] if results.has_key?('facets') instantiated_results = if (fetch || snippets) instantiate_results_from_results(results, fetch, snippets) else instantiate_results_from_db(results) end - paginate === false ? instantiated_results : Pagination.create(instantiated_results, results['matches'], paginate) + paginate === false ? instantiated_results : Pagination.create(instantiated_results, results['matches'], paginate, categories) end protected def instantiate_results_from_db(index_result) @@ -131,17 +135,23 @@ acc end id_map.each do |klass, ids| # replace the id list with an eager-loaded list of records for this model - id_map[klass] = constantize(klass).find(ids) + klass_const = constantize(klass) + if klass_const.respond_to?('find_all_by_id') + id_map[klass] = klass_const.find_all_by_id(ids) + else + id_map[klass] = klass_const.find(ids) + end end # return them in order - results.map do |result| + results = results.map do |result| model, id = result["__type"], result["__id"] id_map[model].detect {|record| id == record.id.to_s } end + results.compact end def instantiate_results_from_results(index_result, fetch = false, snippets = false) results = index_result['results'] return [] if results.empty? @@ -268,23 +278,38 @@ class ModelConfig attr_accessor :index_name attr_accessor :options def initialize(index_name, options, block) - @index_name = index_name - @options = options - @indexes = [] - @variables = [] - @functions = {} + @index_name = index_name + @options = options + @indexes = [] + @categories = [] + @variables = [] + @functions = {} instance_exec &block end - def indexes(field = nil, &block) - @indexes << [field, block] if field + def indexes(field = nil, options = {}, &block) + if field + @indexes << [field, block] + @categories << [field, block] if options[:category] + end @indexes end + + def category(field = nil, options = {}, &block) + categories field, options, &block + end + def categories(field = nil, options = {}, &block) + if field + @categories << [field, block] + end + @categories + end + def variables(&block) @variables << block if block @variables end @@ -308,10 +333,14 @@ def tanker_indexes tanker_config.indexes end + def tanker_categories + tanker_config.categories + end + def tanker_variables tanker_config.variables end # update a create instance from index tank @@ -331,20 +360,20 @@ # attempt to autodetect timestamp if respond_to?(:created_at) data[:timestamp] = created_at.to_i end - + tanker_indexes.each do |field, block| val = block ? instance_exec(&block) : send(field) val = val.join(' ') if Array === val data[field.to_sym] = val.to_s unless val.nil? end data[:__any] = data.values.sort_by{|v| v.to_s}.join " . " data[:__type] = type_name - data[:__id] = self.id + data[:__id] = self.id.is_a?(Fixnum) ? self.id : self.id.to_s data end #dynamically create a snippet read attribute (method) @@ -361,9 +390,18 @@ options[:variables] = tanker_variables.inject({}) do |hash, variables| hash.merge(instance_exec(&variables)) end end + unless tanker_categories.empty? + options[:categories] = {} + tanker_categories.each do |field, block| + val = block ? instance_exec(&block) : send(field) + val = val.join(' ') if Array === val + options[:categories][field] = val.to_s unless val.nil? + end + end + options end # create a unique index based on the model name and unique id def it_doc_id