From d86f6e61e75d07f0ed8b9214a1b8f1e60dccf73a Mon Sep 17 00:00:00 2001
From: Willem van Bergen <willem@vanbergen.org>
Date: Thu, 1 May 2014 06:10:17 -0400
Subject: [PATCH] Clean up auto complete builder to fix ActiveRecord
deprecation warnings.
---
lib/scoped_search/auto_complete_builder.rb | 73 ++++++++++++++++--------------
lib/scoped_search/definition.rb | 2 +-
spec/integration/ordinal_querying_spec.rb | 6 +--
spec/integration/string_querying_spec.rb | 6 +--
4 files changed, 45 insertions(+), 42 deletions(-)
diff --git a/lib/scoped_search/auto_complete_builder.rb b/lib/scoped_search/auto_complete_builder.rb
index 6085bf6..8ab9ac0 100644
--- a/lib/scoped_search/auto_complete_builder.rb
+++ b/lib/scoped_search/auto_complete_builder.rb
@@ -1,17 +1,16 @@
module ScopedSearch
-
- LOGICAL_INFIX_OPERATORS = ScopedSearch::QueryLanguage::Parser::LOGICAL_INFIX_OPERATORS
- LOGICAL_PREFIX_OPERATORS = ScopedSearch::QueryLanguage::Parser::LOGICAL_PREFIX_OPERATORS
- NULL_PREFIX_OPERATORS = ScopedSearch::QueryLanguage::Parser::NULL_PREFIX_OPERATORS
- NULL_PREFIX_COMPLETER = ['has']
- COMPARISON_OPERATORS = ScopedSearch::QueryLanguage::Parser::COMPARISON_OPERATORS
- PREFIX_OPERATORS = LOGICAL_PREFIX_OPERATORS + NULL_PREFIX_OPERATORS
-
# The AutoCompleteBuilder class builds suggestions to complete query based on
# the query language syntax.
class AutoCompleteBuilder
+ LOGICAL_INFIX_OPERATORS = ScopedSearch::QueryLanguage::Parser::LOGICAL_INFIX_OPERATORS
+ LOGICAL_PREFIX_OPERATORS = ScopedSearch::QueryLanguage::Parser::LOGICAL_PREFIX_OPERATORS
+ NULL_PREFIX_OPERATORS = ScopedSearch::QueryLanguage::Parser::NULL_PREFIX_OPERATORS
+ NULL_PREFIX_COMPLETER = ['has']
+ COMPARISON_OPERATORS = ScopedSearch::QueryLanguage::Parser::COMPARISON_OPERATORS
+ PREFIX_OPERATORS = LOGICAL_PREFIX_OPERATORS + NULL_PREFIX_OPERATORS
+
attr_reader :ast, :definition, :query, :tokens
# This method will parse the query string and build suggestion list using the
@@ -174,10 +173,14 @@ def complete_key(name, field, val)
quoted_table = field.key_klass.connection.quote_table_name(field.key_klass.table_name)
quoted_field = field.key_klass.connection.quote_column_name(field.key_field)
field_name = "#{quoted_table}.#{quoted_field}"
- select_clause = "DISTINCT #{field_name}"
- opts = value_conditions(field_name, val).merge(:select => select_clause, :limit => 20)
- field.key_klass.all(opts).map(&field.key_field).compact.map{ |f| "#{name}.#{f} "}
+ field.key_klass
+ .where(value_conditions(field_name, val))
+ .distinct(field_name)
+ .limit(20)
+ .map(&field.key_field)
+ .compact
+ .map { |f| "#{name}.#{f} " }
end
# this method auto-completes values of fields that have a :complete_value marker
@@ -197,10 +200,13 @@ def complete_value
return complete_date_value if field.temporal?
return complete_key_value(field, token, val) if field.key_field
- opts = value_conditions(field.quoted_field, val)
- opts.merge!(:limit => 20, :select => "DISTINCT #{field.quoted_field}")
-
- return completer_scope(field).all(opts).map(&field.field).compact.map{|v| v.to_s =~ /\s+/ ? "\"#{v}\"" : v}
+ completer_scope(field)
+ .where(value_conditions(field.quoted_field, val))
+ .distinct(field.quoted_field)
+ .limit(20)
+ .map(&field.field)
+ .compact
+ .map { |v| v.to_s =~ /\s/ ? "\"#{v}\"" : v }
end
def completer_scope(field)
@@ -215,7 +221,7 @@ def complete_set(field)
end
# date value completer
def complete_date_value
- options =[]
+ options = []
options << '"30 minutes ago"'
options << '"1 hour ago"'
options << '"2 hours ago"'
@@ -233,24 +239,29 @@ def complete_date_value
# complete values in a key-value schema
def complete_key_value(field, token, val)
key_name = token.sub(/^.*\./,"")
- key_opts = value_conditions(field.quoted_field,val).merge(:conditions => {field.key_field => key_name})
- key_klass = field.key_klass.first(key_opts)
+ key_klass = field.key_klass.where(field.key_field => key_name).first
raise ScopedSearch::QueryNotSupported, "Field '#{key_name}' not recognized for searching!" if key_klass.nil?
- opts = {:limit => 20, :select => "DISTINCT #{field.quoted_field}"}
- if(field.key_klass != field.klass)
- key = field.key_klass.to_s.gsub(/.*::/,'').underscore.to_sym
- fk = field.klass.reflections[key].association_foreign_key.to_sym
- opts.merge!(:conditions => {fk => key_klass.id})
- else
- opts.merge!(key_opts)
+ query = completer_scope(field)
+
+ if field.key_klass != field.klass
+ key = field.key_klass.to_s.gsub(/.*::/,'').underscore.to_sym
+ fk = field.klass.reflections[key].association_foreign_key.to_sym
+ query = query.where(fk => key_klass.id)
end
- return completer_scope(field).all(opts).map(&field.field).compact.map{|v| v.to_s =~ /\s+/ ? "\"#{v}\"" : v}
+
+ query
+ .where(value_conditions(field, val))
+ .distinct(field.quoted_field)
+ .limit(20)
+ .map(&field.field)
+ .compact
+ .map { |v| v.to_s =~ /\s/ ? "\"#{v}\"" : v }
end
- #this method returns conditions for selecting completion from partial value
- def value_conditions(field_name, val)
- return val.blank? ? {} : {:conditions => "#{field_name} LIKE '#{val.gsub("'","''")}%'".tr_s('%*', '%')}
+ # This method returns conditions for selecting completion from partial value
+ def value_conditions(field, val)
+ val.blank? ? nil : "#{field.quoted_field} LIKE '#{val.gsub("'","''")}%'".tr_s('%*', '%')
end
# This method complete infix operators by field type
@@ -259,8 +270,4 @@ def complete_operator(node)
end
end
-
end
-
-# Load lib files
-require 'scoped_search/query_builder'
diff --git a/lib/scoped_search/definition.rb b/lib/scoped_search/definition.rb
index 7483857..f5b2c79 100644
--- a/lib/scoped_search/definition.rb
+++ b/lib/scoped_search/definition.rb
@@ -258,7 +258,7 @@ def register_named_scope! # :nodoc
when 4
@klass.scope(:search_for, lambda { |*args|
find_options = ScopedSearch::QueryBuilder.build_query(definition, args[0], args[1])
- search_scope = @klass.all
+ search_scope = @klass
search_scope = search_scope.where(find_options[:conditions]) if find_options[:conditions]
search_scope = search_scope.includes(find_options[:include]) if find_options[:include]
search_scope = search_scope.references(find_options[:include]) if find_options[:include]
diff --git a/spec/integration/ordinal_querying_spec.rb b/spec/integration/ordinal_querying_spec.rb
index 5c591d9..9247682 100644
--- a/spec/integration/ordinal_querying_spec.rb
+++ b/spec/integration/ordinal_querying_spec.rb
@@ -85,10 +85,8 @@
# any implicit type conversions to a string (+ or << operators) a TypeError would be raised.
# https://github.com/wvanbergen/scoped_search/issues/33 for more details
it "encoded string should not raise TypeError when querying non-indexed column without a value" do
- if defined? Encoding
- query = 'unindexed ='.force_encoding(Encoding::UTF_8).encode
- lambda { @class.search_for(query) }.should_not raise_error
- end
+ query = 'unindexed ='.force_encoding(Encoding::UTF_8).encode
+ lambda { @class.search_for(query) }.should_not raise_error
end
it "should not return records for which the query matches unindex records" do
diff --git a/spec/integration/string_querying_spec.rb b/spec/integration/string_querying_spec.rb
index 3008266..029d201 100644
--- a/spec/integration/string_querying_spec.rb
+++ b/spec/integration/string_querying_spec.rb
@@ -221,10 +221,8 @@
end
it "resetting order when selecting distinct values" do
- distinct_search =
- @class.search_for('', :order => '').all(:select => 'DISTINCT(explicit)')
-
- Set.new(distinct_search.map(&:explicit)).should == Set['baz', nil]
+ distinct_search = @class.search_for('', :order => '').distinct(:explicit)
+ Set.new(distinct_search.pluck(:explicit)).should == Set['baz', nil]
end
it 'should order using symbol' do