lib/administrate/search.rb in administrate-0.11.0 vs lib/administrate/search.rb in administrate-0.12.0

- old
+ new

@@ -1,45 +1,118 @@ require "active_support/core_ext/module/delegation" require "active_support/core_ext/object/blank" module Administrate class Search + class Query + attr_reader :filters + + def blank? + terms.blank? && filters.empty? + end + + def initialize(original_query) + @original_query = original_query + @filters, @terms = parse_query(original_query) + end + + def original + @original_query + end + + def terms + @terms.join(" ") + end + + def to_s + original + end + + private + + def filter?(word) + word.match?(/^\w+:$/) + end + + def parse_query(query) + filters = [] + terms = [] + query.to_s.split.each do |word| + if filter?(word) + filters << word.split(":").first + else + terms << word + end + end + [filters, terms] + end + end + def initialize(scoped_resource, dashboard_class, term) @dashboard_class = dashboard_class @scoped_resource = scoped_resource - @term = term + @query = Query.new(term) end def run - if @term.blank? + if query.blank? @scoped_resource.all else - @scoped_resource.joins(tables_to_join).where(query, *search_terms) + results = search_results(@scoped_resource) + results = filter_results(results) + results end end private - def query + def apply_filter(filter, resources) + return resources unless filter + filter.call(resources) + end + + def filter_results(resources) + query.filters.each do |filter_name| + filter = valid_filters[filter_name] + resources = apply_filter(filter, resources) + end + resources + end + + def query_template search_attributes.map do |attr| table_name = query_table_name(attr) attr_name = column_to_query(attr) "LOWER(CAST(#{table_name}.#{attr_name} AS CHAR(256))) LIKE ?" end.join(" OR ") end - def search_terms + def query_values ["%#{term.mb_chars.downcase}%"] * search_attributes.count end def search_attributes attribute_types.keys.select do |attribute| attribute_types[attribute].searchable? end end + def search_results(resources) + resources. + joins(tables_to_join). + where(query_template, *query_values) + end + + def valid_filters + if @dashboard_class.const_defined?(:COLLECTION_FILTERS) + @dashboard_class.const_get(:COLLECTION_FILTERS).stringify_keys + else + {} + end + end + def attribute_types @dashboard_class::ATTRIBUTE_TYPES end def query_table_name(attr) @@ -74,8 +147,12 @@ Administrate::Field::HasMany, Administrate::Field::HasOne, ].include?(attribute_types[attribute].deferred_class) end - attr_reader :resolver, :term + def term + query.terms + end + + attr_reader :resolver, :query end end