scoped_search 2.6.4 → 2.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|