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 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