motor-admin 0.3.3 → 0.3.6

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