scoped_search 2.6.4 → 2.6.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/scoped_search/auto_complete_builder.rb +2 -1
- data/lib/scoped_search/definition.rb +2 -1
- data/lib/scoped_search/query_builder.rb +10 -11
- data/lib/scoped_search/rails_helper.rb +1 -1
- data/lib/scoped_search/version.rb +1 -1
- data/spec/integration/auto_complete_spec.rb +14 -7
- data/spec/integration/relation_querying_spec.rb +50 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3bb6838588ce385873a180ec0e875deedde5fcde
|
4
|
+
data.tar.gz: efbe17ef6dd34eadea7ac3251b3fbf5225e4e2c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa3ed52f60b294fba0ef10b2299882e820d985b26dd03dfdcb0c91b93fb2445c5fe21817e80a4d452eb5f169f68626f4a672e7abb8f7e542a94516a794bcd979
|
7
|
+
data.tar.gz: c43a5e3d499f854bf01ae594387650bf46deaf4e4770ed44047949b2fcd0ca46bcd8ab8312970430fbe58ff9bebea86125a5862c9e840bde4821c94d960bfb05
|
@@ -154,6 +154,7 @@ module ScopedSearch
|
|
154
154
|
def complete_keyword
|
155
155
|
keywords = []
|
156
156
|
definition.fields.each do|f|
|
157
|
+
next unless f[1].complete_enabled
|
157
158
|
if (f[1].key_field)
|
158
159
|
keywords += complete_key(f[0], f[1], tokens.last)
|
159
160
|
else
|
@@ -178,7 +179,7 @@ module ScopedSearch
|
|
178
179
|
field.key_klass.all(opts).map(&field.key_field).compact.map{ |f| "#{name}.#{f} "}
|
179
180
|
end
|
180
181
|
|
181
|
-
# this method auto-completes values of fields that have a :complete_value marker
|
182
|
+
# this method auto-completes values of fields that have a :complete_value marker
|
182
183
|
def complete_value
|
183
184
|
if last_token_is(COMPARISON_OPERATORS)
|
184
185
|
token = tokens[tokens.size-2]
|
@@ -16,7 +16,7 @@ module ScopedSearch
|
|
16
16
|
class Field
|
17
17
|
|
18
18
|
attr_reader :definition, :field, :only_explicit, :relation, :key_relation, :full_text_search,
|
19
|
-
:key_field, :complete_value, :offset, :word_size, :ext_method, :operators
|
19
|
+
:key_field, :complete_value, :complete_enabled, :offset, :word_size, :ext_method, :operators
|
20
20
|
|
21
21
|
# Initializes a Field instance given the definition passed to the
|
22
22
|
# scoped_search call on the ActiveRecord-based model class.
|
@@ -43,6 +43,7 @@ module ScopedSearch
|
|
43
43
|
@only_explicit = !!options[:only_explicit]
|
44
44
|
@full_text_search = options[:full_text_search]
|
45
45
|
@default_operator = options[:default_operator] if options.has_key?(:default_operator)
|
46
|
+
@complete_enabled = options[:complete_enabled].nil? ? true : options[:complete_enabled]
|
46
47
|
end
|
47
48
|
|
48
49
|
# Store this field is the field array
|
@@ -221,16 +221,15 @@ module ScopedSearch
|
|
221
221
|
elsif field.set?
|
222
222
|
return set_test(field, operator, value, &block)
|
223
223
|
elsif field.definition.klass.reflections[field.relation].try(:macro) == :has_many
|
224
|
+
value = value.to_i if field.offset
|
225
|
+
yield(:parameter, value)
|
226
|
+
primary_key = "#{field.definition.klass.quoted_table_name}.#{field.definition.klass.primary_key}"
|
224
227
|
if field.definition.klass.reflections[field.relation].options.has_key?(:through)
|
225
|
-
value = value.to_i if field.offset
|
226
|
-
yield(:parameter, value)
|
227
228
|
join = has_many_through_join(field)
|
228
|
-
|
229
|
-
return "#{field.definition.klass.table_name}.id IN (SELECT #{field.reflection_keys(field.definition.klass.reflections[middle_table])[1]} FROM #{join} WHERE #{field.to_sql(operator, &block)} #{self.sql_operator(operator, field)} ? )"
|
229
|
+
return "#{primary_key} IN (SELECT #{primary_key} FROM #{join} WHERE #{field.to_sql(operator, &block)} #{self.sql_operator(operator, field)} ? )"
|
230
230
|
else
|
231
|
-
|
232
|
-
|
233
|
-
return "#{field.definition.klass.table_name}.id IN (SELECT #{field.reflection_keys(field.definition.klass.reflections[field.relation])[1]} FROM #{field.klass.table_name} WHERE #{field.to_sql(operator, &block)} #{self.sql_operator(operator, field)} ? )"
|
231
|
+
foreign_key = field.reflection_keys(field.definition.klass.reflections[field.relation])[1]
|
232
|
+
return "#{primary_key} IN (SELECT #{foreign_key} FROM #{field.klass.quoted_table_name} WHERE #{field.to_sql(operator, &block)} #{self.sql_operator(operator, field)} ? )"
|
234
233
|
end
|
235
234
|
else
|
236
235
|
value = value.to_i if field.offset
|
@@ -247,10 +246,10 @@ module ScopedSearch
|
|
247
246
|
many_table_name = many_class.table_name
|
248
247
|
middle_table_name = many_class.reflections[through].klass.table_name
|
249
248
|
#primary and foreign keys + optional condition for the many to middle join
|
250
|
-
pk1, fk1
|
249
|
+
pk1, fk1 = field.reflection_keys(many_class.reflections[through])
|
251
250
|
condition1 = field.reflection_conditions(field.klass.reflections[many_table_name.to_sym])
|
252
251
|
#primary and foreign keys + optional condition for the endpoint to middle join
|
253
|
-
pk2, fk2
|
252
|
+
pk2, fk2 = field.reflection_keys(field.klass.reflections[middle_table_name.to_sym])
|
254
253
|
condition2 = field.reflection_conditions(many_class.reflections[field.relation])
|
255
254
|
|
256
255
|
<<-SQL
|
@@ -310,7 +309,7 @@ module ScopedSearch
|
|
310
309
|
key_table = klass.reflections[key].table_name
|
311
310
|
value_table = klass.table_name.to_s
|
312
311
|
|
313
|
-
|
312
|
+
value_table_fk_key, key_table_pk = reflection_keys(klass.reflections[key])
|
314
313
|
|
315
314
|
main_reflection = definition.klass.reflections[relation]
|
316
315
|
if main_reflection
|
@@ -350,7 +349,7 @@ module ScopedSearch
|
|
350
349
|
fk = reflection.options[:foreign_key]
|
351
350
|
# activerecord prior to 3.1 doesn't respond to foreign_key method and hold the key name in the reflection primary key
|
352
351
|
fk ||= reflection.respond_to?(:foreign_key) ? reflection.foreign_key : reflection.primary_key_name
|
353
|
-
[pk, fk]
|
352
|
+
reflection.macro == :belongs_to ? [fk, pk] : [pk, fk]
|
354
353
|
end
|
355
354
|
|
356
355
|
def reflection_conditions(reflection)
|
@@ -134,7 +134,7 @@ module ScopedSearch
|
|
134
134
|
.append( "<a>" + "<strong class='ui-autocomplete-completed'>" + item.completed + "</strong>" + item.part + "</a>" )
|
135
135
|
.appendTo( ul );
|
136
136
|
} else {
|
137
|
-
if(
|
137
|
+
if(typeof(self._renderItemData) === "function") {
|
138
138
|
self._renderItemData( ul, item );
|
139
139
|
} else {
|
140
140
|
self._renderItem( ul, item );
|
@@ -9,30 +9,32 @@ ScopedSearch::RSpec::Database.test_databases.each do |db|
|
|
9
9
|
before(:all) do
|
10
10
|
ScopedSearch::RSpec::Database.establish_named_connection(db)
|
11
11
|
|
12
|
-
ActiveRecord::Migration.create_table(:bars, :force => true) do |t|
|
12
|
+
ActiveRecord::Migration.create_table(:bars, :force => true) do |t|
|
13
13
|
t.integer :foo_id
|
14
14
|
t.string :related
|
15
15
|
end
|
16
16
|
|
17
|
-
ActiveRecord::Migration.create_table(:foos, :force => true) do |t|
|
17
|
+
ActiveRecord::Migration.create_table(:foos, :force => true) do |t|
|
18
18
|
t.string :string
|
19
19
|
t.string :another
|
20
20
|
t.string :explicit
|
21
|
+
t.string :deprecated
|
21
22
|
t.integer :int
|
22
|
-
t.date :date
|
23
|
+
t.date :date
|
23
24
|
t.integer :unindexed
|
24
25
|
end
|
25
26
|
|
26
27
|
class ::Bar < ActiveRecord::Base
|
27
28
|
belongs_to :foo
|
28
29
|
end
|
29
|
-
|
30
|
+
|
30
31
|
class ::Foo < ActiveRecord::Base
|
31
32
|
has_many :bars
|
32
|
-
|
33
|
+
|
33
34
|
scoped_search :on => [:string, :int, :date]
|
34
35
|
scoped_search :on => :another, :default_operator => :eq, :alias => :alias
|
35
36
|
scoped_search :on => :explicit, :only_explicit => true, :complete_value => true
|
37
|
+
scoped_search :on => :deprecated, :complete_enabled => false
|
36
38
|
scoped_search :on => :related, :in => :bars, :rename => 'bars.related'.to_sym
|
37
39
|
end
|
38
40
|
|
@@ -41,13 +43,13 @@ ScopedSearch::RSpec::Database.test_databases.each do |db|
|
|
41
43
|
Foo.create!(:string => 'baz', :another => nil, :explicit => nil , :int => nil, :date => nil , :unindexed => nil)
|
42
44
|
|
43
45
|
Bar.create!(:related => 'lala', :foo => @foo_1)
|
44
|
-
Bar.create!(:related => 'another lala', :foo => @foo_1)
|
46
|
+
Bar.create!(:related => 'another lala', :foo => @foo_1)
|
45
47
|
end
|
46
48
|
|
47
49
|
after(:all) do
|
48
50
|
ActiveRecord::Migration.drop_table(:foos)
|
49
51
|
ActiveRecord::Migration.drop_table(:bars)
|
50
|
-
|
52
|
+
|
51
53
|
Object.send :remove_const, :Foo
|
52
54
|
Object.send :remove_const, :Bar
|
53
55
|
|
@@ -98,6 +100,11 @@ ScopedSearch::RSpec::Database.test_databases.each do |db|
|
|
98
100
|
it "should not repeat logical operators" do
|
99
101
|
Foo.complete_for('string = foo and ').should_not contain("string = foo and and", "string = foo and or")
|
100
102
|
end
|
103
|
+
|
104
|
+
it "should not contain deprecated field in autocompleter" do
|
105
|
+
Foo.complete_for(' ').should_not contain(" deprecated")
|
106
|
+
end
|
107
|
+
|
101
108
|
end
|
102
109
|
|
103
110
|
context 'using an aliased field' do
|
@@ -278,6 +278,56 @@ ScopedSearch::RSpec::Database.test_databases.each do |db|
|
|
278
278
|
end
|
279
279
|
end
|
280
280
|
|
281
|
+
context 'querying a :has_many => :through many relation' do
|
282
|
+
|
283
|
+
before do
|
284
|
+
|
285
|
+
# Create some tables
|
286
|
+
ActiveRecord::Migration.create_table(:zars) { |t| t.integer :baz_id }
|
287
|
+
ActiveRecord::Migration.create_table(:bazs) { |t| t.string :related }
|
288
|
+
ActiveRecord::Migration.create_table(:zoos) { |t| t.integer :zar_id; t.string :foo }
|
289
|
+
|
290
|
+
# The related classes
|
291
|
+
class Zar < ActiveRecord::Base; belongs_to :baz; has_many :zoos; end
|
292
|
+
class Baz < ActiveRecord::Base; has_many :zars; end
|
293
|
+
|
294
|
+
# The class on which to call search_for
|
295
|
+
class Zoo < ActiveRecord::Base
|
296
|
+
belongs_to :zar
|
297
|
+
has_many :bazs, :through => :zar
|
298
|
+
|
299
|
+
scoped_search :in => :bazs, :on => :related
|
300
|
+
end
|
301
|
+
|
302
|
+
baz_1 = Baz.create(:related => 'baz')
|
303
|
+
baz_2 = Baz.create(:related => 'baz too!')
|
304
|
+
|
305
|
+
zar_1 = Zar.create!( :baz => baz_1)
|
306
|
+
zar_2 = Zar.create!( :baz => baz_2)
|
307
|
+
|
308
|
+
Zoo.create!(:zar => zar_1, :foo => 'foo')
|
309
|
+
Zoo.create!(:zar => zar_1, :foo => 'foo too')
|
310
|
+
Zoo.create!(:zar => zar_2, :foo => 'foo three')
|
311
|
+
end
|
312
|
+
|
313
|
+
after do
|
314
|
+
ActiveRecord::Migration.drop_table(:bazs)
|
315
|
+
ActiveRecord::Migration.drop_table(:zars)
|
316
|
+
ActiveRecord::Migration.drop_table(:zoos)
|
317
|
+
end
|
318
|
+
|
319
|
+
# This table schema is not supported in activerecord 2, skip the tests
|
320
|
+
if ActiveRecord::VERSION::MAJOR > 2
|
321
|
+
it "should find the three records that are related to a baz record" do
|
322
|
+
Zoo.search_for('baz').should have(3).items
|
323
|
+
end
|
324
|
+
|
325
|
+
it "should find no records that are related to a baz record" do
|
326
|
+
Zoo.search_for('related=baz AND related="baz too!"').should have(0).items
|
327
|
+
end
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
281
331
|
context 'querying a :has_many => :through :polymorphic relation' do
|
282
332
|
|
283
333
|
before do
|
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: 2.6.
|
4
|
+
version: 2.6.5
|
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: 2014-03-
|
13
|
+
date: 2014-03-10 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|