scoped_search 2.6.1 → 2.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/lib/scoped_search/query_builder.rb +24 -7
- data/lib/scoped_search/version.rb +1 -1
- data/spec/integration/relation_querying_spec.rb +51 -0
- metadata +20 -20
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
MDc4ZmFjZTRlYmMyZDRhZjljYzg2NzFmYWM1OWJkNDllOGQwMmUzOQ==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 37c27d6c6a3311a013c5bcaa5558f3d91f7c4443
|
4
|
+
data.tar.gz: f0d713611729611a6d2f0f990982873dad65bb82
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
ZjBhMmI2YmZlNGNlYTBmNzBmMmZjMjg0Y2NjN2YzZjgwOTA5NjJmMDhlYzg4
|
11
|
-
ODI0MmEyYTI0NGZiN2NjYzBiN2ZlNzA1ZGY1ZDM0Y2FkZDcyMzg=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
NmU5N2UwN2FiOWE1MGI2NDNjNWZkMWEyNGI5YTk2MzIxM2Q5ZTc5YjIwOGQ5
|
14
|
-
N2UzMTg0ODlhMTljZDQ5NDAxNGZiNTMwMDhkODg5MmQ3Yzc3NzNhMGU1Y2I0
|
15
|
-
NTlmMDEwODgxMTk3ZWNiZjI5NjU5N2RjNzE3MzBjMDYwZDk0NzM=
|
6
|
+
metadata.gz: 5826b9fe779a5c48da50101a6dc7c52ba756bed745f99d463adeada1f23a1484e127d36ea122a9249f85050597133748655db51900d40160bf9c81a154975ae2
|
7
|
+
data.tar.gz: 6a0a37aeb76ca59e10c07c3e57ac51480dc34e7ef52586026d9db75741da70619fd327061b459ed527e206725b68e47fb0b4c5b012464f13aea8c48a1a053e90
|
@@ -240,16 +240,25 @@ module ScopedSearch
|
|
240
240
|
end
|
241
241
|
|
242
242
|
def has_many_through_join(field)
|
243
|
+
many_class = field.definition.klass
|
244
|
+
through = many_class.reflections[field.relation].options[:through]
|
245
|
+
#table names
|
243
246
|
endpoint_table_name = field.klass.table_name
|
244
|
-
|
245
|
-
middle_table_name =
|
247
|
+
many_table_name = many_class.table_name
|
248
|
+
middle_table_name = many_class.reflections[through].klass.table_name
|
249
|
+
#primary and foreign keys + optional condition for the many to middle join
|
250
|
+
pk1, fk1 = field.reflection_keys(many_class.reflections[through])
|
251
|
+
condition1 = field.reflection_conditions(field.klass.reflections[many_table_name.to_sym])
|
252
|
+
#primary and foreign keys + optional condition for the endpoint to middle join
|
253
|
+
pk2, fk2 = field.reflection_keys(field.klass.reflections[middle_table_name.to_sym])
|
254
|
+
condition2 = field.reflection_conditions(many_class.reflections[field.relation])
|
246
255
|
|
247
256
|
<<-SQL
|
248
|
-
#{
|
257
|
+
#{many_table_name}
|
249
258
|
INNER JOIN #{middle_table_name}
|
250
|
-
ON #{
|
259
|
+
ON #{many_table_name}.#{pk1} = #{middle_table_name}.#{fk1} #{condition1}
|
251
260
|
INNER JOIN #{endpoint_table_name}
|
252
|
-
ON #{middle_table_name}.#{
|
261
|
+
ON #{middle_table_name}.#{fk2} = #{endpoint_table_name}.#{pk2} #{condition2}
|
253
262
|
SQL
|
254
263
|
end
|
255
264
|
|
@@ -336,14 +345,22 @@ module ScopedSearch
|
|
336
345
|
return join_sql
|
337
346
|
end
|
338
347
|
|
339
|
-
def reflection_keys
|
348
|
+
def reflection_keys(reflection)
|
340
349
|
pk = reflection.klass.primary_key
|
341
350
|
fk = reflection.options[:foreign_key]
|
342
351
|
# activerecord prior to 3.1 doesn't respond to foreign_key method and hold the key name in the reflection primary key
|
343
|
-
fk
|
352
|
+
fk ||= reflection.respond_to?(:foreign_key) ? reflection.foreign_key : reflection.primary_key_name
|
344
353
|
[pk, fk]
|
345
354
|
end
|
346
355
|
|
356
|
+
def reflection_conditions(reflection)
|
357
|
+
return unless reflection
|
358
|
+
conditions = reflection.options[:conditions]
|
359
|
+
conditions ||= "#{reflection.options[:source]}_type = '#{reflection.klass}'" if reflection.options[:source]
|
360
|
+
conditions ||= "#{reflection.try(:foreign_type)} = '#{reflection.klass}'" if reflection.options[:polymorphic]
|
361
|
+
" AND #{conditions}" if conditions
|
362
|
+
end
|
363
|
+
|
347
364
|
def to_ext_method_sql(key, operator, value, &block)
|
348
365
|
raise ScopedSearch::QueryNotSupported, "'#{definition.klass}' doesn't respond to '#{ext_method}'" unless definition.klass.respond_to?(ext_method)
|
349
366
|
conditions = definition.klass.send(ext_method.to_sym,key, operator, value) rescue {}
|
@@ -274,5 +274,56 @@ ScopedSearch::RSpec::Database.test_databases.each do |db|
|
|
274
274
|
Koo.search_for('related=baz AND related="baz too!"').should have(1).items
|
275
275
|
end
|
276
276
|
end
|
277
|
+
|
278
|
+
context 'querying a :has_many => :through :polymorphic relation' do
|
279
|
+
|
280
|
+
before do
|
281
|
+
|
282
|
+
# Create some tables
|
283
|
+
ActiveRecord::Migration.create_table(:taggables) { |t| t.integer :taggable_id; t.string :taggable_type; t.integer :tag_id }
|
284
|
+
ActiveRecord::Migration.create_table(:dogs) { |t| t.string :related }
|
285
|
+
ActiveRecord::Migration.create_table(:tags) { |t| t.string :foo }
|
286
|
+
|
287
|
+
# The related classes
|
288
|
+
class Taggable < ActiveRecord::Base; belongs_to :tag; belongs_to :taggable, :polymorphic => true; end
|
289
|
+
class Tag < ActiveRecord::Base; has_many :taggables; end
|
290
|
+
|
291
|
+
# The class on which to call search_for
|
292
|
+
class Dog < ActiveRecord::Base
|
293
|
+
has_many :taggable, :as => :taggable
|
294
|
+
has_many :tags, :through => :taggable
|
295
|
+
|
296
|
+
scoped_search :in => :tags, :on => :foo
|
297
|
+
end
|
298
|
+
|
299
|
+
@tag_1 = Tag.create!(:foo => 'foo')
|
300
|
+
@tag_2 = Tag.create!(:foo => 'foo too')
|
301
|
+
@tag_3 = Tag.create!(:foo => 'foo three')
|
302
|
+
|
303
|
+
@taggable_1 = Dog.create(:related => 'baz')
|
304
|
+
@taggable_2 = Dog.create(:related => 'baz too!')
|
305
|
+
|
306
|
+
@bar_1 = Taggable.create!(:tag => @tag_1, :taggable => @taggable_1, :taggable_type => 'Dog' )
|
307
|
+
@bar_2 = Taggable.create!(:tag => @tag_1)
|
308
|
+
@bar_3 = Taggable.create!(:tag => @tag_2, :taggable => @taggable_1 , :taggable_type => 'Dog')
|
309
|
+
@bar_3 = Taggable.create!(:tag => @tag_2, :taggable => @taggable_2 , :taggable_type => 'Dog')
|
310
|
+
@bar_3 = Taggable.create!(:tag => @tag_2, :taggable => @taggable_2 , :taggable_type => 'Dog')
|
311
|
+
@bar_4 = Taggable.create!(:tag => @tag_3)
|
312
|
+
end
|
313
|
+
|
314
|
+
after do
|
315
|
+
ActiveRecord::Migration.drop_table(:dogs)
|
316
|
+
ActiveRecord::Migration.drop_table(:taggables)
|
317
|
+
ActiveRecord::Migration.drop_table(:tags)
|
318
|
+
end
|
319
|
+
|
320
|
+
it "should find the two records that are related to a baz record" do
|
321
|
+
Dog.search_for('foo').should have(2).items
|
322
|
+
end
|
323
|
+
|
324
|
+
it "should find the two records that are related to a baz record" do
|
325
|
+
Dog.search_for('foo=foo AND foo="foo too"').should have(1).items
|
326
|
+
end
|
327
|
+
end
|
277
328
|
end
|
278
329
|
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: 2.6.
|
4
|
+
version: 2.6.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Amos Benari
|
@@ -10,20 +10,20 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2014-02-10 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - '>='
|
20
20
|
- !ruby/object:Gem::Version
|
21
21
|
version: 2.1.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
|
-
- -
|
26
|
+
- - '>='
|
27
27
|
- !ruby/object:Gem::Version
|
28
28
|
version: 2.1.0
|
29
29
|
- !ruby/object:Gem::Dependency
|
@@ -44,27 +44,27 @@ dependencies:
|
|
44
44
|
name: rake
|
45
45
|
requirement: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
|
-
- -
|
47
|
+
- - '>='
|
48
48
|
- !ruby/object:Gem::Version
|
49
49
|
version: '0'
|
50
50
|
type: :development
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
|
-
- -
|
54
|
+
- - '>='
|
55
55
|
- !ruby/object:Gem::Version
|
56
56
|
version: '0'
|
57
|
-
description:
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
57
|
+
description: " Scoped search makes it easy to search your ActiveRecord-based models.\n
|
58
|
+
\ \n It will create a named scope :search_for that can be called with a query
|
59
|
+
string. It will build an SQL query using\n the provided query string and a definition
|
60
|
+
that specifies on what fields to search. Because the functionality is\n built
|
61
|
+
on named_scope, the result of the search_for call can be used like any other named_scope,
|
62
|
+
so it can be\n chained with another scope or combined with will_paginate.\n \n
|
63
|
+
\ Because it uses standard SQL, it does not require any setup, indexers or daemons.
|
64
|
+
This makes scoped_search\n suitable to quickly add basic search functionality
|
65
|
+
to your application with little hassle. On the other hand,\n it may not be the
|
66
|
+
best choice if it is going to be used on very large datasets or by a large user
|
67
|
+
base.\n"
|
68
68
|
email:
|
69
69
|
- abenari@redhat.com
|
70
70
|
- willem@railsdoctors.com
|
@@ -136,17 +136,17 @@ require_paths:
|
|
136
136
|
- lib
|
137
137
|
required_ruby_version: !ruby/object:Gem::Requirement
|
138
138
|
requirements:
|
139
|
-
- -
|
139
|
+
- - '>='
|
140
140
|
- !ruby/object:Gem::Version
|
141
141
|
version: '0'
|
142
142
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
143
|
requirements:
|
144
|
-
- -
|
144
|
+
- - '>='
|
145
145
|
- !ruby/object:Gem::Version
|
146
146
|
version: '0'
|
147
147
|
requirements: []
|
148
148
|
rubyforge_project:
|
149
|
-
rubygems_version: 2.
|
149
|
+
rubygems_version: 2.0.3
|
150
150
|
signing_key:
|
151
151
|
specification_version: 4
|
152
152
|
summary: Easily search you ActiveRecord models with a simple query language using
|