motor-admin 0.3.3 → 0.3.6

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: a2381b665cf63ac72903b322e652a119c154215db95b477e4f723eb4c0bbdf97
4
- data.tar.gz: 44ffba20a1acb4206a43abfba8ab58c36cb7fd5ff421926c06347f2df3e7a168
3
+ metadata.gz: eda6baf4fb621527782a8529725aa8b8d794a95e17739f657d8ce03bc377de65
4
+ data.tar.gz: 262bceb177a009a497c84ba318254efe97894d474c98d3fcb3c34d35581d05a9
5
5
  SHA512:
6
- metadata.gz: 3f9c1360a6d42da64df2bfeed16d2765aef367ec535d3469d91b3093e3f12ab640fd72c13f76bc8e26dbccad1813c7583c7fce9d81dd8c725c79cbde92d6df97
7
- data.tar.gz: 17daf2ac024c72d6614ea8fa21814c7f224d325f6f8872d1e8df4bbc54bdfe1019622e6c4570821bb17588645010c3b1e126e4865ca056ba62c492294f3e6202
6
+ metadata.gz: 9b7500eb106243d61258e8c244a62c6a7cf0b70727a2a69c401fd727a49f7922b1d2e0df097e5ac6c5ba5c6ca176fedc95c46dee873b1308cf9445122ce2f7e1
7
+ data.tar.gz: 8fdaa674012474e2db6fd95679476aa0ebbf59bfb2d54589e5816d819b4ec6b327c43929a832bccc969b161e90a5efad59246dc68db9e9944c21cac1244b73c9
@@ -0,0 +1,400 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class UnkownFilterError < NoMethodError
5
+ end
6
+ end
7
+
8
+ module Arel
9
+ module Attributes
10
+ class Relation < Attribute
11
+ attr_accessor :collection, :for_write
12
+
13
+ def initialize(relation, name, collection = false, for_write = false)
14
+ self[:relation] = relation
15
+ self[:name] = name
16
+ @collection = collection
17
+ @for_write = for_write
18
+ end
19
+
20
+ delegate :able_to_type_cast?, to: :relation
21
+
22
+ def table_name
23
+ nil
24
+ end
25
+
26
+ def eql?(other)
27
+ self.class == other.class &&
28
+ relation == other.relation &&
29
+ name == other.name &&
30
+ collection == other.collection
31
+ end
32
+
33
+ delegate :type_cast_for_database, to: :relation
34
+ end
35
+ end
36
+ end
37
+
38
+ module Arel
39
+ module Visitors
40
+ class ToSql
41
+ def visit_Arel_Attributes_Relation(o, collector)
42
+ visit(o.relation, collector)
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ module ActiveRecord
49
+ module Associations
50
+ class AliasTracker
51
+ def initialize(connection, aliases)
52
+ @aliases = aliases
53
+ @connection = connection
54
+ @relation_trail = {}
55
+ end
56
+
57
+ def aliased_table_for_relation(trail, arel_table, &block)
58
+ @relation_trail[trail] ||= aliased_table_for(arel_table, &block)
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ module ActiveRecord
65
+ class PredicateBuilder # :nodoc:
66
+ def self.filter_joins(klass, filters)
67
+ custom = []
68
+ [build_filter_joins(klass, filters, [], custom), custom]
69
+ end
70
+
71
+ def self.build_filter_joins(klass, filters, relations = [], custom = [])
72
+ case filters
73
+ when Array
74
+ filters.each { |f| build_filter_joins(klass, f, relations, custom) }.compact
75
+ when Hash
76
+ filters.each do |key, value|
77
+ if klass.respond_to?(:filters) && klass.filters.key?(key.to_sym)
78
+ js = klass.filters.dig(key.to_sym, :joins)
79
+
80
+ if js.is_a?(Array)
81
+ js.each do |j|
82
+ if j.is_a?(String)
83
+ custom << j
84
+ else
85
+ relations << j
86
+ end
87
+ end
88
+ elsif js
89
+ if js.is_a?(String)
90
+ custom << js
91
+ else
92
+ relations << js
93
+ end
94
+ end
95
+ elsif reflection = klass._reflections[key.to_s]
96
+ if value.is_a?(Hash)
97
+ relations <<
98
+ if reflection.polymorphic?
99
+ value = value.dup
100
+ join_klass = value.delete(:as).safe_constantize
101
+ right_table = join_klass.arel_table
102
+ left_table = reflection.active_record.arel_table
103
+
104
+ on = right_table[join_klass.primary_key]
105
+ .eq(left_table[reflection.foreign_key])
106
+ .and(left_table[reflection.foreign_type].eq(join_klass.name))
107
+
108
+ cross_boundry_joins = join_klass.left_outer_joins(ActiveRecord::PredicateBuilder.filter_joins(join_klass, value).flatten).send(
109
+ :build_joins, []
110
+ )
111
+
112
+ [
113
+ left_table.join(right_table, Arel::Nodes::OuterJoin).on(on).join_sources,
114
+ cross_boundry_joins
115
+ ]
116
+ else
117
+ {
118
+ key => build_filter_joins(reflection.klass, value, [], custom)
119
+ }
120
+ end
121
+ elsif value.is_a?(Array)
122
+ value.each do |v|
123
+ relations << {
124
+ key => build_filter_joins(reflection.klass, v, [], custom)
125
+ }
126
+ end
127
+ elsif value != true && value != false && value != 'true' && value != 'false' && !value.nil?
128
+ relations << key
129
+ end
130
+ elsif !klass.columns_hash.key?(key.to_s) && key.to_s.end_with?('_ids') && reflection = klass._reflections[key.to_s.gsub(
131
+ /_ids$/, 's'
132
+ )]
133
+ relations << reflection.name
134
+ elsif reflection = klass.reflect_on_all_associations(:has_and_belongs_to_many).find do |r|
135
+ r.join_table == key.to_s && value.keys.first.to_s == r.association_foreign_key.to_s
136
+ end
137
+ reflection = klass._reflections[klass._reflections[reflection.name.to_s].send(:delegate_reflection).options[:through].to_s]
138
+ relations << { reflection.name => build_filter_joins(reflection.klass, value) }
139
+ end
140
+ end
141
+ end
142
+
143
+ relations
144
+ end
145
+
146
+ def build_from_filter_hash(attributes, relation_trail, alias_tracker)
147
+ case attributes
148
+ when Array
149
+ node = build_from_filter_hash(attributes.shift, relation_trail, alias_tracker)
150
+
151
+ n = attributes.shift(2)
152
+ until n.empty?
153
+ n[1] = build_from_filter_hash(n[1], relation_trail, alias_tracker)
154
+ if n[0] == 'AND'
155
+ if node.is_a?(Arel::Nodes::And)
156
+ node.children.push(n[1])
157
+ else
158
+ node = node.and(n[1])
159
+ end
160
+ elsif n[0] == 'OR'
161
+ node = Arel::Nodes::Grouping.new(node).or(Arel::Nodes::Grouping.new(n[1]))
162
+ elsif !n[0].is_a?(String)
163
+ n[0] = build_from_filter_hash(n[0], relation_trail, alias_tracker)
164
+ if node.is_a?(Arel::Nodes::And)
165
+ node.children.push(n[0])
166
+ else
167
+ node = node.and(n[0])
168
+ end
169
+ else
170
+ raise 'lll'
171
+ end
172
+ n = attributes.shift(2)
173
+ end
174
+
175
+ node
176
+ when Hash
177
+ expand_from_filter_hash(attributes, relation_trail, alias_tracker)
178
+ else
179
+ expand_from_filter_hash({ id: attributes }, relation_trail, alias_tracker)
180
+ end
181
+ end
182
+
183
+ def expand_from_filter_hash(attributes, relation_trail, alias_tracker)
184
+ klass = table.send(:klass)
185
+
186
+ children = attributes.flat_map do |key, value|
187
+ if klass.respond_to?(:filters) && custom_filter = klass.filters[key]
188
+ instance_exec(klass, table, key, value, relation_trail, alias_tracker, &custom_filter[:block])
189
+ elsif column = klass.columns_hash[key.to_s] || klass.columns_hash[key.to_s.split('.').first]
190
+ expand_filter_for_column(key, column, value, relation_trail)
191
+ elsif relation = klass.reflect_on_association(key)
192
+ expand_filter_for_relationship(relation, value, relation_trail, alias_tracker)
193
+ elsif key.to_s.end_with?('_ids') && relation = klass.reflect_on_association(key.to_s.gsub(/_ids$/, 's'))
194
+ expand_filter_for_relationship(relation, { id: value }, relation_trail, alias_tracker)
195
+ elsif relation = klass.reflect_on_all_associations(:has_and_belongs_to_many).find do |r|
196
+ r.join_table == key.to_s && value.keys.first.to_s == r.association_foreign_key.to_s
197
+ end
198
+ expand_filter_for_join_table(relation, value, relation_trail, alias_tracker)
199
+ else
200
+ raise ActiveRecord::UnkownFilterError, "Unkown filter \"#{key}\" for #{klass}."
201
+ end
202
+ end
203
+
204
+ children.compact!
205
+ if children.size > 1
206
+ Arel::Nodes::And.new(children)
207
+ else
208
+ children.first
209
+ end
210
+ end
211
+
212
+ def expand_filter_for_column(key, column, value, relation_trail)
213
+ attribute = table.arel_table[column.name]
214
+ relation_trail.each do |rt|
215
+ attribute = Arel::Attributes::Relation.new(attribute, rt)
216
+ end
217
+
218
+ if column.type == :json || column.type == :jsonb
219
+ names = key.to_s.split('.')
220
+ names.shift
221
+ attribute = attribute[names]
222
+ end
223
+
224
+ if value.is_a?(Hash)
225
+ nodes = value.map do |subkey, subvalue|
226
+ expand_filter_for_arel_attribute(column, attribute, subkey, subvalue)
227
+ end
228
+ nodes.inject { |c, n| c.nil? ? n : c.and(n) }
229
+ elsif value.nil?
230
+ attribute.eq(nil)
231
+ elsif [true, 'true'].include?(value)
232
+ column.type == :boolean ? attribute.eq(true) : attribute.not_eq(nil)
233
+ elsif [false, 'false'].include?(value)
234
+ column.type == :boolean ? attribute.eq(false) : attribute.eq(nil)
235
+ elsif value.is_a?(Array) && !column.array
236
+ attribute.in(value)
237
+ elsif column.type != :json && column.type != :jsonb
238
+ converted_value = column.array ? Array(value) : value
239
+ attribute.eq(converted_value)
240
+ else
241
+ raise ActiveRecord::UnkownFilterError, "Unkown type for #{column}. (type #{value.class})"
242
+ end
243
+ end
244
+
245
+ def expand_filter_for_arel_attribute(column, attribute, key, value)
246
+ case key.to_sym
247
+ when :contains
248
+ attribute.contains(Arel::Nodes::Casted.new(column.array ? Array(value) : value, attribute))
249
+ when :contained_by
250
+ attribute.contained_by(Arel::Nodes::Casted.new(column.array ? Array(value) : value, attribute))
251
+ when :equal_to, :eq
252
+ attribute.eq(value)
253
+ when :excludes
254
+ attribute.excludes(Arel::Nodes::Casted.new(column.array ? Array(value) : value, attribute))
255
+ when :greater_than, :gt
256
+ attribute.gt(value)
257
+ when :greater_than_or_equal_to, :gteq, :gte
258
+ attribute.gteq(value)
259
+ when :has_key
260
+ attribute.has_key(value)
261
+ when :has_keys
262
+ attribute.has_keys(*Array(value).map { |x| Arel::Nodes.build_quoted(x) })
263
+ when :has_any_key
264
+ attribute.has_any_key(*Array(value).map { |x| Arel::Nodes.build_quoted(x) })
265
+ when :in
266
+ attribute.in(value)
267
+ when :less_than, :lt
268
+ attribute.lt(value)
269
+ when :less_than_or_equal_to, :lteq, :lte
270
+ attribute.lteq(value)
271
+ when :like
272
+ attribute.matches(value, nil, true)
273
+ when :ilike
274
+ attribute.matches(value, nil, false)
275
+ when :not, :not_equal, :neq
276
+ attribute.not_eq(value)
277
+ when :not_in
278
+ attribute.not_in(value)
279
+ when :overlaps
280
+ attribute.overlaps(Arel::Nodes::Casted.new(column.array ? Array(value) : value, attribute))
281
+ when :not_overlaps
282
+ attribute.not_overlaps(value)
283
+ when :ts_match
284
+ if value.is_a?(Array)
285
+ attribute.ts_query(*value)
286
+ else
287
+ attribute.ts_query(value)
288
+ end
289
+ when :within
290
+ case value
291
+ when String
292
+ if /\A[0-9A-F]*\Z/i.match?(value) && value.start_with?('00', '01')
293
+ attribute.within(Arel::Nodes::HexEncodedBinary.new(value))
294
+ else
295
+ attribute.within(Arel::Nodes.build_quoted(value))
296
+ end
297
+ when Hash
298
+ attribute.within(Arel::Nodes.build_quoted(value))
299
+ else
300
+ raise "Not Supported value for within: #{value.inspect}"
301
+ end
302
+ else
303
+ raise "Not Supported: #{key.to_sym} on column \"#{column.name}\" of type #{column.type}"
304
+ end
305
+ end
306
+
307
+ def expand_filter_for_relationship(relation, value, relation_trail, alias_tracker)
308
+ case relation.macro
309
+ when :has_many
310
+ case value
311
+ when true, 'true'
312
+ counter_cache_column_name = relation.counter_cache_column || "#{relation.plural_name}_count"
313
+ if relation.active_record.column_names.include?(counter_cache_column_name.to_s)
314
+ return table.arel_table[counter_cache_column_name.to_sym].gt(0)
315
+ else
316
+ raise "Not Supported: #{relation.name}"
317
+ end
318
+ when false, 'false'
319
+ counter_cache_column_name = relation.counter_cache_column || "#{relation.plural_name}_count"
320
+ if relation.active_record.column_names.include?(counter_cache_column_name.to_s)
321
+ return table.arel_table[counter_cache_column_name.to_sym].eq(0)
322
+ else
323
+ raise "Not Supported: #{relation.name}"
324
+ end
325
+ end
326
+
327
+ when :belongs_to
328
+ if [true, 'true'].include?(value)
329
+ return table.arel_table[relation.foreign_key].not_eq(nil)
330
+ elsif value == false || value == 'false' || value.nil?
331
+ return table.arel_table[relation.foreign_key].eq(nil)
332
+ end
333
+ end
334
+
335
+ if relation.polymorphic?
336
+ value = value.dup
337
+ klass = value.delete(:as).safe_constantize
338
+
339
+ builder = self.class.new(TableMetadata.new(
340
+ klass,
341
+ alias_tracker.aliased_table_for_relation(relation_trail + ["#{klass.table_name}_as_#{relation.name}"],
342
+ klass.arel_table) do
343
+ klass.arel_table.name
344
+ end,
345
+ relation
346
+ ))
347
+ builder.build_from_filter_hash(value, relation_trail + ["#{klass.table_name}_as_#{relation.name}"],
348
+ alias_tracker)
349
+ else
350
+ builder = self.class.new(TableMetadata.new(
351
+ relation.klass,
352
+ alias_tracker.aliased_table_for_relation(relation_trail + [relation.name],
353
+ relation.klass.arel_table) do
354
+ relation.alias_candidate(table.arel_table.name || relation.klass.arel_table)
355
+ end,
356
+ relation
357
+ ))
358
+ builder.build_from_filter_hash(value, relation_trail + [relation.name], alias_tracker)
359
+ end
360
+ end
361
+
362
+ def expand_filter_for_join_table(relation, value, relation_trail, alias_tracker)
363
+ relation = relation.active_record._reflections[relation.active_record._reflections[relation.name.to_s].send(:delegate_reflection).options[:through].to_s]
364
+ builder = self.class.new(TableMetadata.new(
365
+ relation.klass,
366
+ alias_tracker.aliased_table_for_relation(relation_trail + [relation.name],
367
+ relation.klass.arel_table) do
368
+ relation.alias_candidate(table.arel_table.name || relation.klass.arel_table)
369
+ end,
370
+ relation
371
+ ))
372
+ builder.build_from_filter_hash(value, relation_trail + [relation.name], alias_tracker)
373
+ end
374
+ end
375
+ end
376
+
377
+ module ActiveRecord
378
+ class Relation
379
+ class FilterClauseFactory # :nodoc:
380
+ def initialize(klass, predicate_builder)
381
+ @klass = klass
382
+ @predicate_builder = predicate_builder
383
+ end
384
+
385
+ def build(filters, alias_tracker)
386
+ if filters.is_a?(Hash) || filters.is_a?(Array)
387
+ parts = [predicate_builder.build_from_filter_hash(filters, [], alias_tracker)]
388
+ else
389
+ raise ArgumentError, "Unsupported argument type: #{filters.inspect} (#{filters.class})"
390
+ end
391
+
392
+ WhereClause.new(parts)
393
+ end
394
+
395
+ protected
396
+
397
+ attr_reader :klass, :predicate_builder
398
+ end
399
+ end
400
+ end
@@ -40,6 +40,6 @@ require_relative './active_record_utils/fetch_methods'
40
40
  require_relative './active_record_utils/defined_scopes_extension'
41
41
  require_relative './active_record_utils/active_storage_links_extension'
42
42
  require_relative './active_record_utils/active_storage_blob_patch'
43
- require_relative './active_record_utils/active_record_filter_patch'
43
+ require_relative './active_record_utils/active_record_filter'
44
44
  require_relative './active_record_utils/active_record_connection_column_patch'
45
45
  require_relative './active_record_utils/action_text_attribute_patch'
@@ -8,7 +8,10 @@ module Motor
8
8
  def call(rel, params)
9
9
  meta = {}
10
10
 
11
- meta[:count] = rel.limit(nil).offset(nil).reorder(nil).count if params[:meta].to_s.include?('count')
11
+ if params[:meta].to_s.include?('count')
12
+ meta[:count] =
13
+ rel.limit(nil).offset(nil).reorder(nil).select(rel.klass.arel_table[rel.klass.primary_key]).count
14
+ end
12
15
 
13
16
  meta
14
17
  end
@@ -13,12 +13,57 @@ module Motor
13
13
 
14
14
  normalized_params = normalize_params(Array.wrap(params))
15
15
 
16
- rel = rel.filter(normalized_params)
16
+ rel = apply_filters(rel, normalized_params)
17
17
  rel = rel.distinct if can_apply_distinct?(rel)
18
18
 
19
19
  rel
20
20
  end
21
21
 
22
+ def clean_filters(value)
23
+ if value.class.name == 'ActionController::Parameters'
24
+ value.to_unsafe_h
25
+ elsif value.is_a?(Array)
26
+ value.map { |v| clean_filters(v) }
27
+ else
28
+ value
29
+ end
30
+ end
31
+
32
+ def apply_predicates(rel, filters)
33
+ joins = ActiveRecord::PredicateBuilder.filter_joins(rel.klass, filters)
34
+
35
+ joins.flatten.reduce(rel) do |acc, j|
36
+ if j.is_a?(String) || j.is_a?(Arel::Nodes::Join)
37
+ acc.joins(j)
38
+ elsif j.present?
39
+ acc.left_outer_joins(j)
40
+ else
41
+ acc
42
+ end
43
+ end
44
+ end
45
+
46
+ def apply_filters(rel, filters)
47
+ filters = clean_filters(filters)
48
+
49
+ rel = apply_predicates(rel, filters)
50
+
51
+ alias_tracker = ActiveRecord::Associations::AliasTracker.create(rel.connection, rel.table.name, [])
52
+ filter_clause_factory = ActiveRecord::Relation::FilterClauseFactory.new(rel.klass, rel.predicate_builder)
53
+
54
+ where_clause = filter_clause_factory.build(filters, alias_tracker)
55
+
56
+ rel_values = rel.instance_variable_get(:@values)
57
+
58
+ if rel_values[:where]
59
+ rel_values[:where] += where_clause
60
+ else
61
+ rel_values[:where] = where_clause
62
+ end
63
+
64
+ rel
65
+ end
66
+
22
67
  def normalize_params(params)
23
68
  params.map do |item|
24
69
  next item if item.is_a?(String)
@@ -195,7 +195,7 @@ module Motor
195
195
  sql.gsub(STATEMENT_VARIABLE_REGEXP, '?'),
196
196
  attributes.map(&:value))
197
197
 
198
- [sql, 'SQL', attributes]
198
+ [sql, 'SQL', []]
199
199
  end
200
200
 
201
201
  def normalize_sql(sql)
@@ -191,7 +191,9 @@ module Motor
191
191
  if options[:class_name] == 'ActiveStorage::Attachment'
192
192
  klass.has_many_attached name.delete_suffix('_attachments').to_sym
193
193
  elsif filters.present?
194
- klass.has_many(name.to_sym, -> { filter(filters).tap(&:arel) }, **options.symbolize_keys)
194
+ klass.has_many(name.to_sym, lambda {
195
+ Motor::ApiQuery::Filter.apply_filters(all, filters).distinct
196
+ }, **options.symbolize_keys)
195
197
  else
196
198
  klass.has_many(name.to_sym, **options.symbolize_keys)
197
199
  end
data/lib/motor/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Motor
4
- VERSION = '0.3.3'
4
+ VERSION = '0.3.6'
5
5
  end
data/lib/motor.rb CHANGED
@@ -6,7 +6,6 @@ require 'cancancan'
6
6
  require 'ar_lazy_preload'
7
7
  require 'fugit'
8
8
  require 'csv'
9
- require 'active_record/filter'
10
9
  require 'audited'
11
10
  require 'uri'
12
11
  require 'net/http'
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: motor-admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.3.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pete Matsyburka
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-29 00:00:00.000000000 Z
11
+ date: 2022-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: activerecord-filter
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '5.2'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '5.2'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: ar_lazy_preload
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -86,14 +72,14 @@ dependencies:
86
72
  requirements:
87
73
  - - ">="
88
74
  - !ruby/object:Gem::Version
89
- version: '5.2'
75
+ version: '6.0'
90
76
  type: :runtime
91
77
  prerelease: false
92
78
  version_requirements: !ruby/object:Gem::Requirement
93
79
  requirements:
94
80
  - - ">="
95
81
  - !ruby/object:Gem::Version
96
- version: '5.2'
82
+ version: '6.0'
97
83
  description: |
98
84
  Motor Admin allows to create a flexible admin panel with writing less code.
99
85
  All customizations to the admin panel can be made directly in the UI without
@@ -171,7 +157,7 @@ files:
171
157
  - lib/motor/active_record_utils.rb
172
158
  - lib/motor/active_record_utils/action_text_attribute_patch.rb
173
159
  - lib/motor/active_record_utils/active_record_connection_column_patch.rb
174
- - lib/motor/active_record_utils/active_record_filter_patch.rb
160
+ - lib/motor/active_record_utils/active_record_filter.rb
175
161
  - lib/motor/active_record_utils/active_storage_blob_patch.rb
176
162
  - lib/motor/active_record_utils/active_storage_links_extension.rb
177
163
  - lib/motor/active_record_utils/defined_scopes_extension.rb
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- ActiveRecord::Filter.module_eval do
4
- def filters
5
- @filters ||= HashWithIndifferentAccess.new
6
- end
7
- end
8
-
9
- if Rails::VERSION::MAJOR == 6
10
- ActiveRecord::Relation::Filter.module_eval do
11
- def build_arel(aliases = nil)
12
- arel = super
13
- my_alias_tracker = ActiveRecord::Associations::AliasTracker.create(connection, table.name, [])
14
- build_filters(arel, my_alias_tracker)
15
- arel
16
- end
17
-
18
- def build_filters(manager, alias_tracker)
19
- return unless @filters
20
-
21
- where_clause = nil
22
-
23
- @filters.each do |filters|
24
- where_clause = filter_clause_factory.build(filters, alias_tracker)
25
-
26
- manager.where(where_clause.ast)
27
- end
28
-
29
- @values[:where] = where_clause if where_clause
30
- end
31
- end
32
- end