scoped_search 3.2.0 → 3.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fa5c8206f13488ac53e60199ef5a08fc825c8654
4
- data.tar.gz: ad9258a231663b704d4bc28728059c19f1846fb5
3
+ metadata.gz: f8e91bf7d864d576d7020bd56184d9ed7173e5c3
4
+ data.tar.gz: 502a182f6303fb040a4b3e77f54d984a85d54093
5
5
  SHA512:
6
- metadata.gz: d9201e227813757d3fb3cba025d2692ab946f74206912c95b5b04db74932b2a350a7323085084a99ee7560afb584de91eb5cd931cad515403662170486121c53
7
- data.tar.gz: 29db95daea73ad5e2f4fa789dec6029d685ae2360a36d2063d6c58004191e1e202e25ab16f38a98d6dce3d5eb1b8b1ca0e74838a91892927254a366f4f7fce1e
6
+ metadata.gz: ce108bace0ec727d852a4e0d9db9d330bab9d157a4dd985d0bb77e88eff186553462451beaee8fc532ac8d0b95361174b60772511ee7e1016be5c6f3640fe16e
7
+ data.tar.gz: c5dcd4e411820161628a61cf0485bf457121ba4ab8338f12d3723f83d8a2938bb1b85469eab096bce6f96f9b76bfb65af58723973de9d63f8e996692cfa4c3b4
@@ -176,11 +176,12 @@ module ScopedSearch
176
176
 
177
177
  field.key_klass
178
178
  .where(value_conditions(field_name, val))
179
- .select("DISTINCT #{field_name}")
179
+ .select(field_name)
180
180
  .limit(20)
181
181
  .map(&field.key_field)
182
182
  .compact
183
183
  .map { |f| "#{name}.#{f} " }
184
+ .uniq
184
185
  end
185
186
 
186
187
  # this method auto-completes values of fields that have a :complete_value marker
@@ -201,12 +202,13 @@ module ScopedSearch
201
202
  return complete_key_value(field, token, val) if field.key_field
202
203
 
203
204
  completer_scope(field)
204
- .where(value_conditions(field, val))
205
- .select("DISTINCT #{field.quoted_field}")
205
+ .where(value_conditions(field.quoted_field, val))
206
+ .select(field.quoted_field)
206
207
  .limit(20)
207
208
  .map(&field.field)
208
209
  .compact
209
210
  .map { |v| v.to_s =~ /\s/ ? "\"#{v}\"" : v }
211
+ .uniq
210
212
  end
211
213
 
212
214
  def completer_scope(field)
@@ -251,7 +253,7 @@ module ScopedSearch
251
253
  end
252
254
 
253
255
  query
254
- .where(value_conditions(field, val))
256
+ .where(value_conditions(field.quoted_field, val))
255
257
  .select("DISTINCT #{field.quoted_field}")
256
258
  .limit(20)
257
259
  .map(&field.field)
@@ -260,8 +262,8 @@ module ScopedSearch
260
262
  end
261
263
 
262
264
  # This method returns conditions for selecting completion from partial value
263
- def value_conditions(field, val)
264
- val.blank? ? nil : "CAST(#{field.quoted_field} as CHAR(50)) LIKE '#{val.gsub("'","''")}%'".tr_s('%*', '%')
265
+ def value_conditions(field_name, val)
266
+ val.blank? ? nil : "CAST(#{field_name} as CHAR(50)) LIKE '#{val.gsub("'","''")}%'".tr_s('%*', '%')
265
267
  end
266
268
 
267
269
  # This method complete infix operators by field type
@@ -250,7 +250,7 @@ module ScopedSearch
250
250
  def register_named_scope! # :nodoc
251
251
  definition = self
252
252
  @klass.scope(:search_for, proc { |query, options|
253
- search_scope = ActiveRecord::VERSION::MAJOR == 3 ? @klass.scoped : @klass
253
+ search_scope = ActiveRecord::VERSION::MAJOR == 3 ? @klass.scoped : (ActiveRecord::VERSION::MINOR < 1 ? @klass.where(nil) : @klass.all)
254
254
 
255
255
  find_options = ScopedSearch::QueryBuilder.build_query(definition, query || '', options || {})
256
256
  search_scope = search_scope.where(find_options[:conditions]) if find_options[:conditions]
@@ -83,17 +83,21 @@ module ScopedSearch
83
83
  return find_attributes
84
84
  end
85
85
 
86
- def order_by(order, &block)
86
+ def find_field_for_order_by(order, &block)
87
87
  order ||= definition.default_order
88
- return nil if order.blank?
88
+ return [nil, nil] if order.blank?
89
89
  field_name, direction_name = order.to_s.split(/\s+/, 2)
90
90
  field = definition.field_by_name(field_name)
91
91
  raise ScopedSearch::QueryNotSupported, "the field '#{field_name}' in the order statement is not valid field for search" unless field
92
+ return field, direction_name
93
+ end
94
+
95
+ def order_by(order, &block)
96
+ field, direction_name = find_field_for_order_by(order, &block)
97
+ return nil if field.nil?
92
98
  sql = field.to_sql(&block)
93
99
  direction = (!direction_name.nil? && direction_name.downcase.eql?('desc')) ? " DESC" : " ASC"
94
- order = sql + direction
95
-
96
- return order
100
+ return sql + direction
97
101
  end
98
102
 
99
103
  # A hash that maps the operators of the query language with the corresponding SQL operator.
@@ -516,7 +520,10 @@ module ScopedSearch
516
520
 
517
521
  def order_by(order, &block)
518
522
  sql = super(order, &block)
519
- sql += sql.include?('DESC') ? ' NULLS LAST ' : ' NULLS FIRST ' if sql
523
+ if sql
524
+ field, _ = find_field_for_order_by(order, &block)
525
+ sql += sql.include?('DESC') ? ' NULLS LAST ' : ' NULLS FIRST ' if !field.nil? && field.column.null
526
+ end
520
527
  sql
521
528
  end
522
529
  end
@@ -22,7 +22,7 @@ module ScopedSearch
22
22
 
23
23
  ascend = "#{field} ASC"
24
24
  descend = "#{field} DESC"
25
- selected = [ascend, descend].include?(params[:order])
25
+ selected_sort = [ascend, descend].find { |o| o == params[:order] }
26
26
 
27
27
  case params[:order]
28
28
  when ascend
@@ -33,9 +33,9 @@ module ScopedSearch
33
33
  new_sort = ["ASC", "DESC"].include?(options[:default]) ? "#{field} #{options[:default]}" : ascend
34
34
  end
35
35
 
36
- if selected
36
+ unless selected_sort.nil?
37
37
  css_classes = html_options[:class] ? html_options[:class].split(" ") : []
38
- if new_sort == ascend
38
+ if selected_sort == ascend
39
39
  options[:as] = "&#9650;&nbsp;#{options[:as]}"
40
40
  css_classes << "ascending"
41
41
  else
@@ -1,3 +1,3 @@
1
1
  module ScopedSearch
2
- VERSION = "3.2.0"
2
+ VERSION = "3.2.1"
3
3
  end
@@ -89,6 +89,10 @@ ScopedSearch::RSpec::Database.test_databases.each do |db|
89
89
  Foo.complete_for('date ').should =~ (["date = ", "date < ", "date > "])
90
90
  end
91
91
 
92
+ it "should complete when query is already distinct" do
93
+ Foo.uniq.complete_for('int =').length.should > 0
94
+ end
95
+
92
96
  it "should raise error for unindexed field" do
93
97
  lambda { Foo.complete_for('unindexed = 10 ')}.should raise_error(ScopedSearch::QueryNotSupported)
94
98
  end
@@ -91,6 +91,10 @@ require "spec_helper"
91
91
  Item.complete_for('facts.').length.should == 2
92
92
  end
93
93
 
94
+ it "should complete facts names with partial name" do
95
+ Item.complete_for('facts.c').length.should == 1
96
+ end
97
+
94
98
  it "should complete values for fact name = color" do
95
99
  Item.complete_for('facts.color = ').length.should == 2
96
100
  end
@@ -31,6 +31,51 @@ ScopedSearch::RSpec::Database.test_databases.each do |db|
31
31
  ScopedSearch::RSpec::Database.close_connection
32
32
  end
33
33
 
34
+ context 'with no scoped_search defaults' do
35
+
36
+ before(:all) do
37
+ @class2 = ScopedSearch::RSpec::Database.create_model(
38
+ :string => :string,
39
+ :another => :string,
40
+ ) do |klass|
41
+ klass.scoped_search :on => :string
42
+ klass.scoped_search :on => :another
43
+ end
44
+
45
+ @class2.create!(:string => 'foo', :another => 'foo')
46
+ @class2.create!(:string => 'bar', :another => 'foo')
47
+ @class2.create!(:string => 'baz', :another => 'bar')
48
+ end
49
+
50
+ after(:all) do
51
+ ScopedSearch::RSpec::Database.drop_model(@class2)
52
+ end
53
+
54
+ context '#search_for with an empty string' do
55
+
56
+ it 'should not remove previous scope' do
57
+ @class2.where(another: 'foo').search_for('').count.should == 2
58
+ end
59
+
60
+ it 'should return an ActiveRecord::Relation' do
61
+ @class2.search_for('').should be_a(ActiveRecord::Relation)
62
+ end
63
+
64
+ end
65
+
66
+ context '#search_for with nil' do
67
+ it 'should not remove previous scope' do
68
+ @class2.where(another: 'foo').search_for(nil).count.should == 2
69
+ end
70
+
71
+ it 'should return an ActiveRecord::Relation' do
72
+ @class2.search_for(nil).should be_a(ActiveRecord::Relation)
73
+ end
74
+
75
+ end
76
+
77
+ end
78
+
34
79
  context 'in an implicit string field' do
35
80
  it "should find the record with an exact string match" do
36
81
  @class.search_for('foo').length.should == 1
@@ -70,4 +70,26 @@ describe ScopedSearch::RailsHelper do
70
70
  params[:order] = "field ASC"
71
71
  sort("other")
72
72
  end
73
+
74
+ it "should add no styling by default" do
75
+ should_receive(:url_for)
76
+ should_receive(:a_link).with('Field', anything, hash_excluding(:class))
77
+ sort("field")
78
+ end
79
+
80
+ it "should add ascending style for current ascending sort order " do
81
+ should_receive(:url_for)
82
+ should_receive(:a_link).with('&#9650;&nbsp;Field', anything, hash_including(:class => 'ascending'))
83
+
84
+ params[:order] = "field ASC"
85
+ sort("field")
86
+ end
87
+
88
+ it "should add descending style for current descending sort order " do
89
+ should_receive(:url_for)
90
+ should_receive(:a_link).with('&#9660;&nbsp;Field', anything, hash_including(:class => 'descending'))
91
+
92
+ params[:order] = "field DESC"
93
+ sort("field")
94
+ end
73
95
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scoped_search
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.0
4
+ version: 3.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Amos Benari
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-02-23 00:00:00.000000000 Z
13
+ date: 2015-06-23 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord