motor-admin 0.3.2 → 0.3.5

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: ae8c77e2060615e55e3687dcd6533663f5138ce123ea83340d2db166946f0bab
4
- data.tar.gz: 7668ec7c88bd1a79991b58a495ae1b258f071a98ddb6f525c63c58bc1af3dae5
3
+ metadata.gz: ce4fa10d33b3f41a5a0ba509b53d7815631c1980b521839ecc51f7f80ed548aa
4
+ data.tar.gz: 35d3b13d657714f909ab7fc56f088fc3270b0e40e1839aadc5cf227c99e78fc2
5
5
  SHA512:
6
- metadata.gz: 65c679d3f20748a8f1b7dc5c86fcd4b3ad7206c58698322a524ee7cc384cc9d2bf07c21190d1b6879435c52bb8db2ebc3702dafda540e57761222f902dc3834b
7
- data.tar.gz: 8de97edaa8a1e81f0e4387ba5db19feba94b5557302ac5e52ea01892d6a4ef0f2dd5a8d45729213fe786b248b8dee65c8b8270e35bf36fa7a85b4a8d6daafa96
6
+ metadata.gz: b6c79c98ff08d7402cfc54ff91c661616f2b87bced25af12ff0637a99327fdb000455e9bd32fd78ffe611e3007acfd01104f74b39f5318a1dcdf2798151db733
7
+ data.tar.gz: ba7f58cfd0500b1aa6b9f7b7659afd718f05b548da8597384cc2d036b08c1d4a54c5aa291ddb05b9ebda05cb65bdf08d3bc19e6c6d553d9ab12b3bb0b12dd437
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  <div align="center">
2
2
 
3
- [![Motor Admin](https://user-images.githubusercontent.com/5418788/140520844-a947845d-b579-4b3f-9b49-c539ad3cf580.png)](https://www.getmotoradmin.com)
3
+ [![Motor Admin Rails](https://user-images.githubusercontent.com/5418788/140520844-a947845d-b579-4b3f-9b49-c539ad3cf580.png)](https://www.getmotoradmin.com/ruby-on-rails)
4
4
 
5
- # Motor Admin
5
+ # Motor Admin Rails
6
6
 
7
7
  Low-code Admin panel and Business intelligence Rails engine **(no DSL - configurable from the UI)**.
8
8
 
@@ -0,0 +1,400 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class UnkownFilterError < NoMethodError
5
+ end
6
+ end
7
+
8
+ ActiveRecord::QueryMethods.module_eval do
9
+ def build_arel_with_distinct_on(aliases = nil)
10
+ arel = build_arel_without_distinct_on(aliases)
11
+ arel.distinct_on(distinct_on_values) unless distinct_on_values.empty?
12
+ arel
13
+ end
14
+
15
+ alias_method :build_arel, :build_arel_with_distinct_on
16
+ end
17
+
18
+ module ActiveRecord
19
+ module Associations
20
+ class AliasTracker
21
+ def initialize(connection, aliases)
22
+ @aliases = aliases
23
+ @connection = connection
24
+ @relation_trail = {}
25
+ end
26
+
27
+ def aliased_table_for_relation(trail, arel_table, &block)
28
+ @relation_trail[trail] ||= aliased_table_for(arel_table, &block)
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ module ActiveRecord
35
+ class PredicateBuilder # :nodoc:
36
+ def self.filter_joins(klass, filters)
37
+ custom = []
38
+ [build_filter_joins(klass, filters, [], custom), custom]
39
+ end
40
+
41
+ def self.build_filter_joins(klass, filters, relations = [], custom = [])
42
+ case filters
43
+ when Array
44
+ filters.each { |f| build_filter_joins(klass, f, relations, custom) }.compact
45
+ when Hash
46
+ filters.each do |key, value|
47
+ if klass.respond_to?(:filters) && klass.filters.key?(key.to_sym)
48
+ js = klass.filters.dig(key.to_sym, :joins)
49
+
50
+ if js.is_a?(Array)
51
+ js.each do |j|
52
+ if j.is_a?(String)
53
+ custom << j
54
+ else
55
+ relations << j
56
+ end
57
+ end
58
+ elsif js
59
+ if js.is_a?(String)
60
+ custom << js
61
+ else
62
+ relations << js
63
+ end
64
+ end
65
+ elsif reflection = klass._reflections[key.to_s]
66
+ if value.is_a?(Hash)
67
+ relations << if reflection.polymorphic?
68
+ value = value.dup
69
+ join_klass = value.delete(:as).safe_constantize
70
+ right_table = join_klass.arel_table
71
+ left_table = reflection.active_record.arel_table
72
+
73
+ on = right_table[join_klass.primary_key]
74
+ .eq(left_table[reflection.foreign_key])
75
+ .and(left_table[reflection.foreign_type].eq(join_klass.name))
76
+
77
+ cross_boundry_joins = join_klass.left_outer_joins(ActiveRecord::PredicateBuilder.filter_joins(join_klass, value).flatten).send(
78
+ :build_joins, []
79
+ )
80
+
81
+ [
82
+ left_table.join(right_table, Arel::Nodes::OuterJoin).on(on).join_sources,
83
+ cross_boundry_joins
84
+ ]
85
+ else
86
+ {
87
+ key => build_filter_joins(reflection.klass, value, [], custom)
88
+ }
89
+ end
90
+ elsif value.is_a?(Array)
91
+ value.each do |v|
92
+ relations << {
93
+ key => build_filter_joins(reflection.klass, v, [], custom)
94
+ }
95
+ end
96
+ elsif value != true && value != false && value != 'true' && value != 'false' && !value.nil?
97
+ relations << key
98
+ end
99
+ elsif !klass.columns_hash.key?(key.to_s) && key.to_s.end_with?('_ids') && reflection = klass._reflections[key.to_s.gsub(
100
+ /_ids$/, 's'
101
+ )]
102
+ relations << reflection.name
103
+ elsif reflection = klass.reflect_on_all_associations(:has_and_belongs_to_many).find do |r|
104
+ r.join_table == key.to_s && value.keys.first.to_s == r.association_foreign_key.to_s
105
+ end
106
+ reflection = klass._reflections[klass._reflections[reflection.name.to_s].send(:delegate_reflection).options[:through].to_s]
107
+ relations << { reflection.name => build_filter_joins(reflection.klass, value) }
108
+ end
109
+ end
110
+ end
111
+
112
+ relations
113
+ end
114
+
115
+ def build_from_filter_hash(attributes, relation_trail, alias_tracker)
116
+ case attributes
117
+ when Array
118
+ node = build_from_filter_hash(attributes.shift, relation_trail, alias_tracker)
119
+
120
+ n = attributes.shift(2)
121
+ until n.empty?
122
+ n[1] = build_from_filter_hash(n[1], relation_trail, alias_tracker)
123
+ if n[0] == 'AND'
124
+ if node.is_a?(Arel::Nodes::And)
125
+ node.children.push(n[1])
126
+ else
127
+ node = node.and(n[1])
128
+ end
129
+ elsif n[0] == 'OR'
130
+ node = Arel::Nodes::Grouping.new(node).or(Arel::Nodes::Grouping.new(n[1]))
131
+ elsif !n[0].is_a?(String)
132
+ n[0] = build_from_filter_hash(n[0], relation_trail, alias_tracker)
133
+ if node.is_a?(Arel::Nodes::And)
134
+ node.children.push(n[0])
135
+ else
136
+ node = node.and(n[0])
137
+ end
138
+ else
139
+ raise 'lll'
140
+ end
141
+ n = attributes.shift(2)
142
+ end
143
+
144
+ node
145
+ when Hash
146
+ expand_from_filter_hash(attributes, relation_trail, alias_tracker)
147
+ else
148
+ expand_from_filter_hash({ id: attributes }, relation_trail, alias_tracker)
149
+ end
150
+ end
151
+
152
+ def expand_from_filter_hash(attributes, relation_trail, alias_tracker)
153
+ klass = table.send(:klass)
154
+
155
+ children = attributes.flat_map do |key, value|
156
+ if klass.respond_to?(:filters) && custom_filter = klass.filters[key]
157
+ instance_exec(klass, table, key, value, relation_trail, alias_tracker, &custom_filter[:block])
158
+ elsif column = klass.columns_hash[key.to_s] || klass.columns_hash[key.to_s.split('.').first]
159
+ expand_filter_for_column(key, column, value, relation_trail)
160
+ elsif relation = klass.reflect_on_association(key)
161
+ expand_filter_for_relationship(relation, value, relation_trail, alias_tracker)
162
+ elsif key.to_s.end_with?('_ids') && relation = klass.reflect_on_association(key.to_s.gsub(/_ids$/, 's'))
163
+ expand_filter_for_relationship(relation, { id: value }, relation_trail, alias_tracker)
164
+ elsif relation = klass.reflect_on_all_associations(:has_and_belongs_to_many).find do |r|
165
+ r.join_table == key.to_s && value.keys.first.to_s == r.association_foreign_key.to_s
166
+ end
167
+ expand_filter_for_join_table(relation, value, relation_trail, alias_tracker)
168
+ else
169
+ raise ActiveRecord::UnkownFilterError, "Unkown filter \"#{key}\" for #{klass}."
170
+ end
171
+ end
172
+
173
+ children.compact!
174
+ if children.size > 1
175
+ Arel::Nodes::And.new(children)
176
+ else
177
+ children.first
178
+ end
179
+ end
180
+
181
+ def expand_filter_for_column(key, column, value, relation_trail)
182
+ attribute = table.arel_table[column.name]
183
+ relation_trail.each do |rt|
184
+ attribute = Arel::Attributes::Relation.new(attribute, rt)
185
+ end
186
+
187
+ if column.type == :json || column.type == :jsonb
188
+ names = key.to_s.split('.')
189
+ names.shift
190
+ attribute = attribute[names]
191
+ end
192
+
193
+ if value.is_a?(Hash)
194
+ nodes = value.map do |subkey, subvalue|
195
+ expand_filter_for_arel_attribute(column, attribute, subkey, subvalue)
196
+ end
197
+ nodes.inject { |c, n| c.nil? ? n : c.and(n) }
198
+ elsif value.nil?
199
+ attribute.eq(nil)
200
+ elsif [true, 'true'].include?(value)
201
+ column.type == :boolean ? attribute.eq(true) : attribute.not_eq(nil)
202
+ elsif [false, 'false'].include?(value)
203
+ column.type == :boolean ? attribute.eq(false) : attribute.eq(nil)
204
+ elsif value.is_a?(Array) && !column.array
205
+ attribute.in(value)
206
+ elsif column.type != :json && column.type != :jsonb
207
+ converted_value = column.array ? Array(value) : value
208
+ attribute.eq(converted_value)
209
+ else
210
+ raise ActiveRecord::UnkownFilterError, "Unkown type for #{column}. (type #{value.class})"
211
+ end
212
+ end
213
+
214
+ def expand_filter_for_arel_attribute(column, attribute, key, value)
215
+ case key.to_sym
216
+ when :contains
217
+ attribute.contains(Arel::Nodes::Casted.new(column.array ? Array(value) : value, attribute))
218
+ when :contained_by
219
+ attribute.contained_by(Arel::Nodes::Casted.new(column.array ? Array(value) : value, attribute))
220
+ when :equal_to, :eq
221
+ attribute.eq(value)
222
+ when :excludes
223
+ attribute.excludes(Arel::Nodes::Casted.new(column.array ? Array(value) : value, attribute))
224
+ when :greater_than, :gt
225
+ attribute.gt(value)
226
+ when :greater_than_or_equal_to, :gteq, :gte
227
+ attribute.gteq(value)
228
+ when :has_key
229
+ attribute.has_key(value)
230
+ when :has_keys
231
+ attribute.has_keys(*Array(value).map { |x| Arel::Nodes.build_quoted(x) })
232
+ when :has_any_key
233
+ attribute.has_any_key(*Array(value).map { |x| Arel::Nodes.build_quoted(x) })
234
+ when :in
235
+ attribute.in(value)
236
+ when :intersects
237
+ # geometry_value = if value.is_a?(Hash) # GeoJSON
238
+ # Arel::Nodes::NamedFunction.new('ST_GeomFromGeoJSON', [JSON.generate(value)])
239
+ # elsif # EWKB
240
+ # elsif # WKB
241
+ # elsif # EWKT
242
+ # elsif # WKT
243
+ # end
244
+
245
+ # TODO: us above if to determin if SRID sent
246
+ geometry_value = if value.is_a?(Hash)
247
+ Arel::Nodes::NamedFunction.new('ST_SetSRID',
248
+ [
249
+ Arel::Nodes::NamedFunction.new('ST_GeomFromGeoJSON',
250
+ [Arel::Nodes.build_quoted(JSON.generate(subvalue))]), 4326
251
+ ])
252
+ elsif value[0, 1] == "\x00" || value[0, 1] == "\x01" || value[0, 4] =~ /[0-9a-fA-F]{4}/
253
+ Arel::Nodes::NamedFunction.new('ST_SetSRID',
254
+ [
255
+ Arel::Nodes::NamedFunction.new('ST_GeomFromEWKB',
256
+ [Arel::Nodes.build_quoted(subvalue)]), 4326
257
+ ])
258
+ else
259
+ Arel::Nodes::NamedFunction.new('ST_SetSRID',
260
+ [
261
+ Arel::Nodes::NamedFunction.new('ST_GeomFromText',
262
+ [Arel::Nodes.build_quoted(subvalue)]), 4326
263
+ ])
264
+ end
265
+
266
+ Arel::Nodes::NamedFunction.new('ST_Intersects', [attribute, geometry_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.2'
4
+ VERSION = '0.3.5'
5
5
  end
data/lib/motor.rb CHANGED
@@ -6,11 +6,11 @@ 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'
13
12
  require 'net/https'
13
+ require 'arel/extensions'
14
14
 
15
15
  module Motor
16
16
  PATH = Pathname.new(__dir__)
@@ -3966,9 +3966,9 @@
3966
3966
  "images/marker-icon-2x.png": "images/marker-icon-2x.png",
3967
3967
  "images/marker-icon.png": "images/marker-icon.png",
3968
3968
  "images/marker-shadow.png": "images/marker-shadow.png",
3969
- "main-8ed8d8ad01708ae44fdc.css.gz": "main-8ed8d8ad01708ae44fdc.css.gz",
3970
- "main-8ed8d8ad01708ae44fdc.js.LICENSE.txt": "main-8ed8d8ad01708ae44fdc.js.LICENSE.txt",
3971
- "main-8ed8d8ad01708ae44fdc.js.gz": "main-8ed8d8ad01708ae44fdc.js.gz",
3972
- "main.css": "main-8ed8d8ad01708ae44fdc.css",
3973
- "main.js": "main-8ed8d8ad01708ae44fdc.js"
3969
+ "main-53a1a9dffc796b4ca695.css.gz": "main-53a1a9dffc796b4ca695.css.gz",
3970
+ "main-53a1a9dffc796b4ca695.js.LICENSE.txt": "main-53a1a9dffc796b4ca695.js.LICENSE.txt",
3971
+ "main-53a1a9dffc796b4ca695.js.gz": "main-53a1a9dffc796b4ca695.js.gz",
3972
+ "main.css": "main-53a1a9dffc796b4ca695.css",
3973
+ "main.js": "main-53a1a9dffc796b4ca695.js"
3974
3974
  }
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: motor-admin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.5
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-26 00:00:00.000000000 Z
11
+ date: 2022-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: activerecord-filter
14
+ name: arel-extensions
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '5.2'
19
+ version: '6.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: '5.2'
26
+ version: '6.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: ar_lazy_preload
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -86,14 +86,14 @@ dependencies:
86
86
  requirements:
87
87
  - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: '5.2'
89
+ version: '6.0'
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
- version: '5.2'
96
+ version: '6.0'
97
97
  description: |
98
98
  Motor Admin allows to create a flexible admin panel with writing less code.
99
99
  All customizations to the admin panel can be made directly in the UI without
@@ -171,7 +171,7 @@ files:
171
171
  - lib/motor/active_record_utils.rb
172
172
  - lib/motor/active_record_utils/action_text_attribute_patch.rb
173
173
  - lib/motor/active_record_utils/active_record_connection_column_patch.rb
174
- - lib/motor/active_record_utils/active_record_filter_patch.rb
174
+ - lib/motor/active_record_utils/active_record_filter.rb
175
175
  - lib/motor/active_record_utils/active_storage_blob_patch.rb
176
176
  - lib/motor/active_record_utils/active_storage_links_extension.rb
177
177
  - lib/motor/active_record_utils/defined_scopes_extension.rb
@@ -2219,8 +2219,8 @@ files:
2219
2219
  - ui/dist/images/marker-icon-2x.png
2220
2220
  - ui/dist/images/marker-icon.png
2221
2221
  - ui/dist/images/marker-shadow.png
2222
- - ui/dist/main-8ed8d8ad01708ae44fdc.css.gz
2223
- - ui/dist/main-8ed8d8ad01708ae44fdc.js.gz
2222
+ - ui/dist/main-53a1a9dffc796b4ca695.css.gz
2223
+ - ui/dist/main-53a1a9dffc796b4ca695.js.gz
2224
2224
  - ui/dist/manifest.json
2225
2225
  homepage:
2226
2226
  licenses:
@@ -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