activerecord-filter 6.0.0.7 → 6.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f04e35c30cfd4a96db7ba90fa1221a808121bacde16bdb70080e105274ae33d5
4
- data.tar.gz: 5aabf016e7b0cec65b87b09f191fd0da5eb55b0f48cdf94cf4f1727b2c0867af
3
+ metadata.gz: 0a22c93c0080f2e92aaf6b427e89eb6ac73210bc40304941e7e17373b70c987c
4
+ data.tar.gz: 7180d339c3fed586489cd65a4de59e34d5edaf7860584c12683f144134844470
5
5
  SHA512:
6
- metadata.gz: af710f6e3adfd0b3dab81c34a9ae1b2578e9d6047f81c0fed362e30dd97a06ee110eb189eb670bd3e0875792196a36f574e35051585aef37ec0eaca4b4849b69
7
- data.tar.gz: 869eab8791079a03a395f45ce510d31f05fb0399914ab6996cf8ef4ff4f3450da6a70941cd6068c24a193d4923ac12a539aea4620f16da292c9ae610b77a4419
6
+ metadata.gz: 4950a8448ea79f7a1ea671889e1353b28657722b3eab8ba202d6c80b02f0d16a2ee9ca4c7893fd24b9b3a436e7a95c7c7a87568345ae6b565a22e8791cec5b51
7
+ data.tar.gz: a061d579c68764f56729d2afba8a979f67804d285b6e1ac895e6ce20722d382e4a636b583b9598607f57340535baae2b369b4d4fcb67e28e8b0599de46c5adbd
@@ -4,6 +4,20 @@ require 'arel/extensions'
4
4
  class ActiveRecord::UnkownFilterError < NoMethodError
5
5
  end
6
6
 
7
+ class ActiveRecord::Associations::AliasTracker
8
+
9
+ def initialize(connection, aliases)
10
+ @aliases = aliases
11
+ @connection = connection
12
+ @relation_trail = {}
13
+ end
14
+
15
+ def aliased_table_for_relation(trail, arel_table, &block)
16
+ @relation_trail[trail] ||= aliased_table_for(arel_table, &block)
17
+ end
18
+
19
+ end
20
+
7
21
  module ActiveRecord::Filter
8
22
 
9
23
  delegate :filter, :filter_for, to: :all
@@ -60,16 +74,21 @@ module ActiveRecord
60
74
  elsif reflection = klass._reflections[key.to_s]
61
75
  if value.is_a?(Hash)
62
76
  relations << if reflection.polymorphic?
63
- join_klass = value[:as].safe_constantize
64
-
65
- right_table = join_klass.arel_table.alias("#{join_klass.table_name}_as_#{reflection.name}")
77
+ value = value.dup
78
+ join_klass = value.delete(:as).safe_constantize
79
+ right_table = join_klass.arel_table
66
80
  left_table = reflection.active_record.arel_table
67
81
 
68
82
  on = right_table[join_klass.primary_key].
69
83
  eq(left_table[reflection.foreign_key]).
70
84
  and(left_table[reflection.foreign_type].eq(join_klass.name))
71
85
 
72
- left_table.join(right_table, Arel::Nodes::OuterJoin).on(on).join_sources
86
+ cross_boundry_joins = join_klass.left_outer_joins(ActiveRecord::PredicateBuilder.filter_joins(join_klass, value).flatten).send(:build_joins, [])
87
+
88
+ [
89
+ left_table.join(right_table, Arel::Nodes::OuterJoin).on(on).join_sources,
90
+ cross_boundry_joins
91
+ ]
73
92
  else
74
93
  {
75
94
  key => build_filter_joins(reflection.klass, value, [], custom)
@@ -84,7 +103,7 @@ module ActiveRecord
84
103
  elsif value != true && value != false && value != 'true' && value != 'false' && !value.nil?
85
104
  relations << key
86
105
  end
87
- elsif !klass.columns_hash.has_key?(key.to_s) && key.to_s.ends_with?('_ids') && reflection = klass._reflections[key.to_s.gsub(/_ids$/, 's')]
106
+ elsif !klass.columns_hash.has_key?(key.to_s) && key.to_s.end_with?('_ids') && reflection = klass._reflections[key.to_s.gsub(/_ids$/, 's')]
88
107
  relations << reflection.name
89
108
  elsif reflection = klass.reflect_on_all_associations(:has_and_belongs_to_many).find {|r| r.join_table == key.to_s && value.keys.first.to_s == r.association_foreign_key.to_s }
90
109
  reflection = klass._reflections[klass._reflections[reflection.name.to_s].send(:delegate_reflection).options[:through].to_s]
@@ -142,7 +161,7 @@ module ActiveRecord
142
161
  expand_filter_for_column(key, column, value, relation_trail)
143
162
  elsif relation = klass.reflect_on_association(key)
144
163
  expand_filter_for_relationship(relation, value, relation_trail, alias_tracker)
145
- elsif key.to_s.ends_with?('_ids') && relation = klass.reflect_on_association(key.to_s.gsub(/_ids$/, 's'))
164
+ elsif key.to_s.end_with?('_ids') && relation = klass.reflect_on_association(key.to_s.gsub(/_ids$/, 's'))
146
165
  expand_filter_for_relationship(relation, {id: value}, relation_trail, alias_tracker)
147
166
  elsif relation = klass.reflect_on_all_associations(:has_and_belongs_to_many).find {|r| r.join_table == key.to_s && value.keys.first.to_s == r.association_foreign_key.to_s }
148
167
  expand_filter_for_join_table(relation, value, relation_trail, alias_tracker)
@@ -160,7 +179,7 @@ module ActiveRecord
160
179
  end
161
180
 
162
181
  def expand_filter_for_column(key, column, value, relation_trail)
163
- attribute = table.arel_attribute(column.name)
182
+ attribute = table.arel_table[column.name]
164
183
  relation_trail.each do |rt|
165
184
  attribute = Arel::Attributes::Relation.new(attribute, rt)
166
185
  end
@@ -196,13 +215,13 @@ module ActiveRecord
196
215
  def expand_filter_for_arel_attribute(column, attribute, key, value)
197
216
  case key.to_sym
198
217
  when :contains
199
- attribute.contains(column.array ? Array(value) : value)
218
+ attribute.contains(Arel::Nodes::Casted.new(column.array ? Array(value) : value, attribute))
200
219
  when :contained_by
201
- attribute.contained_by(column.array ? Array(value) : value)
220
+ attribute.contained_by(Arel::Nodes::Casted.new(column.array ? Array(value) : value, attribute))
202
221
  when :equal_to, :eq
203
222
  attribute.eq(value)
204
223
  when :excludes
205
- attribute.excludes(Array(value))
224
+ attribute.excludes(Arel::Nodes::Casted.new(column.array ? Array(value) : value, attribute))
206
225
  when :greater_than, :gt
207
226
  attribute.gt(value)
208
227
  when :greater_than_or_equal_to, :gteq, :gte
@@ -245,7 +264,7 @@ module ActiveRecord
245
264
  when :not_in
246
265
  attribute.not_in(value)
247
266
  when :overlaps
248
- attribute.overlaps(value)
267
+ attribute.overlaps(Arel::Nodes::Casted.new(column.array ? Array(value) : value, attribute))
249
268
  when :not_overlaps
250
269
  attribute.not_overlaps(value)
251
270
  when :ts_match
@@ -277,14 +296,14 @@ module ActiveRecord
277
296
  if value == true || value == 'true'
278
297
  counter_cache_column_name = relation.counter_cache_column || "#{relation.plural_name}_count"
279
298
  if relation.active_record.column_names.include?(counter_cache_column_name.to_s)
280
- return table.arel_attribute(counter_cache_column_name.to_sym).gt(0)
299
+ return table.arel_table[counter_cache_column_name.to_sym].gt(0)
281
300
  else
282
301
  raise "Not Supported: #{relation.name}"
283
302
  end
284
303
  elsif value == false || value == 'false'
285
304
  counter_cache_column_name = relation.counter_cache_column || "#{relation.plural_name}_count"
286
305
  if relation.active_record.column_names.include?(counter_cache_column_name.to_s)
287
- return table.arel_attribute(counter_cache_column_name.to_sym).eq(0)
306
+ return table.arel_table[counter_cache_column_name.to_sym].eq(0)
288
307
  else
289
308
  raise "Not Supported: #{relation.name}"
290
309
  end
@@ -292,33 +311,31 @@ module ActiveRecord
292
311
 
293
312
  when :belongs_to
294
313
  if value == true || value == 'true'
295
- return table.arel_attribute(relation.foreign_key).not_eq(nil)
314
+ return table.arel_table[relation.foreign_key].not_eq(nil)
296
315
  elsif value == false || value == 'false' || value.nil?
297
- return table.arel_attribute(relation.foreign_key).eq(nil)
316
+ return table.arel_table[relation.foreign_key].eq(nil)
298
317
  end
299
318
  end
300
319
 
301
- builder = if relation.polymorphic?
320
+ if relation.polymorphic?
302
321
  value = value.dup
303
322
  klass = value.delete(:as).safe_constantize
304
323
 
305
- self.class.new(TableMetadata.new(
306
- klass,
307
- Arel::Table.new("#{klass.table_name}_as_#{relation.name}", type_caster: klass.type_caster),
324
+ builder = self.class.new(TableMetadata.new(
325
+ klass,
326
+ alias_tracker.aliased_table_for_relation(relation_trail + ["#{klass.table_name}_as_#{relation.name}"], klass.arel_table) { klass.arel_table.name },
308
327
  relation
309
328
  ))
329
+ builder.build_from_filter_hash(value, relation_trail + ["#{klass.table_name}_as_#{relation.name}"], alias_tracker)
310
330
  else
311
- self.class.new(TableMetadata.new(
331
+ builder = self.class.new(TableMetadata.new(
312
332
  relation.klass,
313
- alias_tracker.aliased_table_for(
314
- relation.table_name,
315
- relation.alias_candidate(table.send(:arel_table).name),
316
- relation.klass.type_caster
317
- ),
333
+ alias_tracker.aliased_table_for_relation(relation_trail + [relation.name], relation.klass.arel_table) { relation.alias_candidate(table.arel_table.name || relation.klass.arel_table) },
318
334
  relation
319
335
  ))
336
+ builder.build_from_filter_hash(value, relation_trail + [relation.name], alias_tracker)
320
337
  end
321
- builder.build_from_filter_hash(value, relation_trail + [relation.name], alias_tracker)
338
+
322
339
  end
323
340
 
324
341
 
@@ -326,11 +343,7 @@ module ActiveRecord
326
343
  relation = relation.active_record._reflections[relation.active_record._reflections[relation.name.to_s].send(:delegate_reflection).options[:through].to_s]
327
344
  builder = self.class.new(TableMetadata.new(
328
345
  relation.klass,
329
- alias_tracker.aliased_table_for(
330
- relation.table_name,
331
- relation.alias_candidate(table.send(:arel_table).name),
332
- relation.klass.type_caster
333
- ),
346
+ alias_tracker.aliased_table_for_relation(relation_trail + [relation.name], relation.klass.arel_table) { relation.alias_candidate(table.arel_table.name || relation.klass.arel_table) },
334
347
  relation
335
348
  ))
336
349
  builder.build_from_filter_hash(value, relation_trail + [relation.name], alias_tracker)
@@ -424,7 +437,7 @@ class ActiveRecord::Relation
424
437
  arel
425
438
  end
426
439
 
427
- def build_filters(manager, aliases)
440
+ def build_filters(manager, alias_tracker)
428
441
  @filters.each do |filters|
429
442
  manager.where(filter_clause_factory.build(filters, alias_tracker).ast)
430
443
  end
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module Filter
3
- VERSION = '6.0.0.7'
3
+ VERSION = '6.1.0.rc1'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-filter
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.0.7
4
+ version: 6.1.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Bracy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-26 00:00:00.000000000 Z
11
+ date: 2020-12-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 6.0.0
19
+ version: 6.1.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 6.0.0
26
+ version: 6.1.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: arel-extensions
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 6.0.0.8
33
+ version: 6.1.0.rc2
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 6.0.0.8
40
+ version: 6.1.0.rc2
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: pg
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 6.0.0
61
+ version: 6.1.0
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 6.0.0
68
+ version: 6.1.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: bundler
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -142,14 +142,14 @@ dependencies:
142
142
  requirements:
143
143
  - - ">="
144
144
  - !ruby/object:Gem::Version
145
- version: 6.0.0
145
+ version: 6.1.0
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - ">="
151
151
  - !ruby/object:Gem::Version
152
- version: 6.0.0
152
+ version: 6.1.0
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: faker
155
155
  requirement: !ruby/object:Gem::Requirement
@@ -207,11 +207,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
207
207
  version: '0'
208
208
  required_rubygems_version: !ruby/object:Gem::Requirement
209
209
  requirements:
210
- - - ">="
210
+ - - ">"
211
211
  - !ruby/object:Gem::Version
212
- version: '0'
212
+ version: 1.3.1
213
213
  requirements: []
214
- rubygems_version: 3.1.2
214
+ rubygems_version: 3.1.4
215
215
  signing_key:
216
216
  specification_version: 4
217
217
  summary: A safe way to accept user parameters and query against your ActiveRecord