forest_admin_datasource_active_record 1.16.8 → 1.16.10

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: b3e8b30ef3f95fc128694705efcd7509c6a1afd990d074eb3ce09a8cfd1d56de
4
- data.tar.gz: f6b623bff7a10521c6dc576f38b208cd6037b6f7f4f105bd60c17b8a51bccd6a
3
+ metadata.gz: 6396b9a1d0e2de94e373c7db9e4c8fbb300698db9ec16724fe1d130bd182ba9f
4
+ data.tar.gz: 1da6eb7faf485ddb8739efee58c3ec7764d6b481ca7fac4e7e065272be74c0f2
5
5
  SHA512:
6
- metadata.gz: 2ab6cb755bd266907e7a01328e181c4925dea18be178ff259021dc4a38be564def1d05097dc505c8ba6acc280406481feb4cdc031a9db47e20a964fdaa2a7cd6
7
- data.tar.gz: c4cf3ef5321bf3f4a076f368fccd2461a7a262d3e5d206f781fa70b8bdd7575ab7f25244fb885610c93637abe1b026fb6fb2528af272c777e0b9d00c9d5bbdd7
6
+ metadata.gz: 60ce959c8c390eb61e2f21a8049198d099bc0957669195ee0f44dbd7f845b75ce205da27b31234950b9bc94af171b0e14aa7419fd4fd0b7a529bc8bd15dc043a
7
+ data.tar.gz: 528dc9598f86d83713975ee9b63f444bb47cd0c3f5f0176122ddc5084814a918c9a59c30f3330513bc5e45cbe69587c9e1aaf2630d50038ea3eed6d2d3f6bff2
@@ -37,8 +37,8 @@ module ForestAdminDatasourceActiveRecord
37
37
 
38
38
  def apply_sort(sort)
39
39
  sort.each do |sort_clause|
40
- field = format_field(sort_clause[:field])
41
- @query = @query.order(field => sort_clause[:ascending] ? :asc : :desc)
40
+ resolved = resolve_field(sort_clause[:field])
41
+ @query = @query.order(resolved[:formatted] => sort_clause[:ascending] ? :asc : :desc)
42
42
  end
43
43
 
44
44
  @query
@@ -65,7 +65,9 @@ module ForestAdminDatasourceActiveRecord
65
65
  end
66
66
 
67
67
  def compute_main_operator(condition_tree, aggregator)
68
- field = format_field(condition_tree.field)
68
+ resolved = resolve_field(condition_tree.field)
69
+ field = resolved[:formatted]
70
+ arel_attr = resolved[:arel_attr]
69
71
  value = condition_tree.value
70
72
  aggregator = aggregator.to_sym
71
73
 
@@ -93,45 +95,45 @@ module ForestAdminDatasourceActiveRecord
93
95
  when Operators::NOT_EQUAL, Operators::NOT_IN
94
96
  @query = query_aggregator(aggregator, @collection.model.where.not({ field => value }))
95
97
  when Operators::GREATER_THAN
96
- @query = query_aggregator(aggregator, build_comparison_query(condition_tree.field, field, value, :gt))
98
+ @query = query_aggregator(aggregator, build_comparison_query(condition_tree.field, arel_attr, value, :gt))
97
99
  when Operators::GREATER_THAN_OR_EQUAL
98
- @query = query_aggregator(aggregator, build_comparison_query(condition_tree.field, field, value, :gteq))
100
+ @query = query_aggregator(aggregator, build_comparison_query(condition_tree.field, arel_attr, value, :gteq))
99
101
  when Operators::LESS_THAN
100
- @query = query_aggregator(aggregator, build_comparison_query(condition_tree.field, field, value, :lt))
102
+ @query = query_aggregator(aggregator, build_comparison_query(condition_tree.field, arel_attr, value, :lt))
101
103
  when Operators::LESS_THAN_OR_EQUAL
102
- @query = query_aggregator(aggregator, build_comparison_query(condition_tree.field, field, value, :lteq))
104
+ @query = query_aggregator(aggregator, build_comparison_query(condition_tree.field, arel_attr, value, :lteq))
103
105
  when Operators::CONTAINS
104
106
  @query = query_aggregator(aggregator,
105
- @collection.model.where(@arel_table[field.to_sym].matches("%#{value}%")))
107
+ @collection.model.where(arel_attr.matches("%#{value}%")))
106
108
  when Operators::I_CONTAINS
107
- lower_field = Arel::Nodes::NamedFunction.new('LOWER', [@arel_table[field.to_sym]])
109
+ lower_field = Arel::Nodes::NamedFunction.new('LOWER', [arel_attr])
108
110
  @query = query_aggregator(aggregator,
109
111
  @collection.model.where(lower_field.matches("%#{value.to_s.downcase}%")))
110
112
  when Operators::NOT_CONTAINS
111
113
  @query = query_aggregator(aggregator,
112
- @collection.model.where.not(@arel_table[field.to_sym].matches("%#{value}%")))
114
+ @collection.model.where.not(arel_attr.matches("%#{value}%")))
113
115
  when Operators::NOT_I_CONTAINS
114
- lower_field = Arel::Nodes::NamedFunction.new('LOWER', [@arel_table[field.to_sym]])
116
+ lower_field = Arel::Nodes::NamedFunction.new('LOWER', [arel_attr])
115
117
  @query = query_aggregator(aggregator,
116
118
  @collection.model.where.not(lower_field.matches("%#{value.to_s.downcase}%")))
117
119
  when Operators::STARTS_WITH
118
120
  @query = query_aggregator(aggregator,
119
- @collection.model.where(@arel_table[field.to_sym].matches("#{value}%")))
121
+ @collection.model.where(arel_attr.matches("#{value}%")))
120
122
  when Operators::I_STARTS_WITH
121
- lower_field = Arel::Nodes::NamedFunction.new('LOWER', [@arel_table[field.to_sym]])
123
+ lower_field = Arel::Nodes::NamedFunction.new('LOWER', [arel_attr])
122
124
  @query = query_aggregator(aggregator,
123
125
  @collection.model.where(lower_field.matches("#{value.to_s.downcase}%")))
124
126
  when Operators::ENDS_WITH
125
127
  @query = query_aggregator(aggregator,
126
- @collection.model.where(@arel_table[field.to_sym].matches("%#{value}")))
128
+ @collection.model.where(arel_attr.matches("%#{value}")))
127
129
  when Operators::I_ENDS_WITH
128
- lower_field = Arel::Nodes::NamedFunction.new('LOWER', [@arel_table[field.to_sym]])
130
+ lower_field = Arel::Nodes::NamedFunction.new('LOWER', [arel_attr])
129
131
  @query = query_aggregator(aggregator,
130
132
  @collection.model.where(lower_field.matches("%#{value.to_s.downcase}")))
131
133
  when Operators::LIKE
132
- @query = query_aggregator(aggregator, @collection.model.where(@arel_table[field.to_sym].matches(value)))
134
+ @query = query_aggregator(aggregator, @collection.model.where(arel_attr.matches(value)))
133
135
  when Operators::I_LIKE
134
- lower_field = Arel::Nodes::NamedFunction.new('LOWER', [@arel_table[field.to_sym]])
136
+ lower_field = Arel::Nodes::NamedFunction.new('LOWER', [arel_attr])
135
137
  @query = query_aggregator(aggregator,
136
138
  @collection.model.where(lower_field.matches(value.to_s.downcase)))
137
139
  when Operators::MATCH
@@ -148,23 +150,24 @@ module ForestAdminDatasourceActiveRecord
148
150
 
149
151
  # Use database-specific regex syntax
150
152
  adapter_name = @collection.model.connection.adapter_name.downcase
153
+ table_and_column = "#{arel_attr.relation.name}.#{arel_attr.name}"
151
154
  regex_clause = case adapter_name
152
155
  when 'postgresql'
153
- "#{@arel_table.name}.#{field} ~ ?"
156
+ "#{table_and_column} ~ ?"
154
157
  when 'mysql2', 'mysql', 'sqlite', 'sqlite3'
155
- "#{@arel_table.name}.#{field} REGEXP ?"
158
+ "#{table_and_column} REGEXP ?"
156
159
  else
157
160
  raise ArgumentError, "Match operator is not supported for database adapter '#{adapter_name}'"
158
161
  end
159
162
 
160
163
  @query = query_aggregator(aggregator, @collection.model.where(regex_clause, pattern))
161
164
  when Operators::INCLUDES_ALL
162
- @query = query_aggregator(aggregator, @collection.model.where(@arel_table[field.to_sym].matches_all(value)))
165
+ @query = query_aggregator(aggregator, @collection.model.where(arel_attr.matches_all(value)))
163
166
  when Operators::SHORTER_THAN
164
- length_func = Arel::Nodes::NamedFunction.new('LENGTH', [@arel_table[field.to_sym]])
167
+ length_func = Arel::Nodes::NamedFunction.new('LENGTH', [arel_attr])
165
168
  @query = query_aggregator(aggregator, @collection.model.where(length_func.lt(value)))
166
169
  when Operators::LONGER_THAN
167
- length_func = Arel::Nodes::NamedFunction.new('LENGTH', [@arel_table[field.to_sym]])
170
+ length_func = Arel::Nodes::NamedFunction.new('LENGTH', [arel_attr])
168
171
  @query = query_aggregator(aggregator, @collection.model.where(length_func.gt(value)))
169
172
  end
170
173
 
@@ -213,35 +216,43 @@ module ForestAdminDatasourceActiveRecord
213
216
  @query
214
217
  end
215
218
 
216
- def format_field(field)
217
- if field.include?(':')
218
- relation_name, field = field.split(':')
219
+ def resolve_field(original_field)
220
+ if original_field.include?(':')
221
+ relation_name, column_name = original_field.split(':')
219
222
  relation = @collection.schema[:fields][relation_name]
220
- table_name = @collection.datasource.get_collection(relation.foreign_collection).model.table_name
223
+ related_collection = @collection.datasource.get_collection(relation.foreign_collection)
221
224
  add_join_relation(relation_name)
222
225
 
223
- return "#{table_name}.#{field}"
226
+ {
227
+ formatted: "#{related_collection.model.table_name}.#{column_name}",
228
+ arel_attr: related_collection.model.arel_table[column_name.to_sym]
229
+ }
230
+ else
231
+ {
232
+ formatted: original_field,
233
+ arel_attr: @arel_table[original_field.to_sym]
234
+ }
224
235
  end
225
-
226
- field
227
236
  end
228
237
 
229
- def build_comparison_query(original_field, formatted_field, value, operator)
238
+ def build_comparison_query(original_field, arel_attr, value, operator)
230
239
  # When comparing a String field with a numeric value, compare the length of the string
231
240
  # Otherwise, do a lexicographic comparison
232
241
  if value.is_a?(Numeric)
233
242
  field_schema = ForestAdminDatasourceToolkit::Utils::Collection.get_field_schema(@collection, original_field)
234
243
  if field_schema.column_type == 'String'
235
- length_func = Arel::Nodes::NamedFunction.new('LENGTH', [@arel_table[formatted_field.to_sym]])
244
+ length_func = Arel::Nodes::NamedFunction.new('LENGTH', [arel_attr])
236
245
  return @collection.model.where(length_func.send(operator, value))
237
246
  end
238
247
  end
239
248
 
240
- @collection.model.where(@arel_table[formatted_field.to_sym].send(operator, value))
249
+ @collection.model.where(arel_attr.send(operator, value))
241
250
  end
242
251
 
243
252
  def query_aggregator(aggregator, query)
244
253
  if !@query.respond_to?(:where_clause) || @query.where_clause.empty?
254
+ # Preserve includes from @query when replacing with new query
255
+ query = query.includes(@query.includes_values) if @query.includes_values.any?
245
256
  query
246
257
  else
247
258
  @query.send(aggregator, query)
@@ -10,7 +10,7 @@ module ForestAdminDatasourceActiveRecord
10
10
  @aggregation = aggregation
11
11
  @limit = limit
12
12
  @operation = aggregation.operation.downcase
13
- @field = aggregation.field.nil? ? '*' : format_field(aggregation.field)
13
+ @field = aggregation.field.nil? ? '*' : resolve_field(aggregation.field)[:formatted]
14
14
  end
15
15
 
16
16
  def get
@@ -19,7 +19,7 @@ module ForestAdminDatasourceActiveRecord
19
19
 
20
20
  group_fields = []
21
21
  @aggregation.groups.each do |group|
22
- field = format_field(group[:field])
22
+ field = resolve_field(group[:field])[:formatted]
23
23
  if group[:operation]
24
24
  # Pass original field name for validation before SQL generation
25
25
  date_trunc_expression = date_trunc_sql(group[:operation], field, group[:field])
@@ -1,3 +1,3 @@
1
1
  module ForestAdminDatasourceActiveRecord
2
- VERSION = "1.16.8"
2
+ VERSION = "1.16.10"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forest_admin_datasource_active_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.16.8
4
+ version: 1.16.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthieu
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2025-12-05 00:00:00.000000000 Z
12
+ date: 2025-12-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord