scoped_search 2.6.1 → 2.6.2

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 CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- YzUyZjNjZjdmMDY2MTgzNzJkYjExNWI2NzY5MjMyYmMwNWEzMzUwNQ==
5
- data.tar.gz: !binary |-
6
- MDc4ZmFjZTRlYmMyZDRhZjljYzg2NzFmYWM1OWJkNDllOGQwMmUzOQ==
2
+ SHA1:
3
+ metadata.gz: 37c27d6c6a3311a013c5bcaa5558f3d91f7c4443
4
+ data.tar.gz: f0d713611729611a6d2f0f990982873dad65bb82
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- YzE3ZjUwNmJlZjc4YTMyM2Q1YmM4NmI3MmI2ZGY1MzUxY2RiZDExZThiMDYw
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
- middle_table = field.definition.klass.reflections[field.relation].options[:through]
245
- middle_table_name = field.definition.klass.reflections[middle_table].klass.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
- #{field.definition.klass.table_name}
257
+ #{many_table_name}
249
258
  INNER JOIN #{middle_table_name}
250
- ON #{field.definition.klass.table_name}.id = #{middle_table_name}.#{field.reflection_keys(field.definition.klass.reflections[middle_table])[1]}
259
+ ON #{many_table_name}.#{pk1} = #{middle_table_name}.#{fk1} #{condition1}
251
260
  INNER JOIN #{endpoint_table_name}
252
- ON #{middle_table_name}.#{field.reflection_keys(field.klass.reflections[middle_table])[1]} = #{endpoint_table_name}.id
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 reflection
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 = fk || reflection.respond_to?(:foreign_key) ? reflection.foreign_key : reflection.primary_key_name
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 {}
@@ -1,3 +1,3 @@
1
1
  module ScopedSearch
2
- VERSION = "2.6.1"
2
+ VERSION = "2.6.2"
3
3
  end
@@ -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.1
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: 2013-12-17 00:00:00.000000000 Z
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: ! " Scoped search makes it easy to search your ActiveRecord-based
58
- models.\n \n It will create a named scope :search_for that can be called with
59
- a query string. It will build an SQL query using\n the provided query string
60
- and a definition that specifies on what fields to search. Because the functionality
61
- is\n built on named_scope, the result of the search_for call can be used like
62
- any other named_scope, so it can be\n chained with another scope or combined
63
- with will_paginate.\n \n Because it uses standard SQL, it does not require
64
- any setup, indexers or daemons. This makes scoped_search\n suitable to quickly
65
- add basic search functionality to your application with little hassle. On the other
66
- hand,\n it may not be the best choice if it is going to be used on very large
67
- datasets or by a large user base.\n"
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.1.4
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