forest_liana 9.14.0 → 9.14.2

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: 133660170841c0069ffdc0da3e2a4918e4147f417eae55c87b79bb300d9924b0
4
- data.tar.gz: eba503c46d489b6f6a4e81f26764f284574db290aed180755c6ca33841fc8b19
3
+ metadata.gz: a594bcf7830da0f415fbfadfa90d985e46814d07cda6892f317f1834db731ce3
4
+ data.tar.gz: a565c34a7ef4c7b6e637818963a76b11d772cd716b3eed1db7ffe6b4e8711d2f
5
5
  SHA512:
6
- metadata.gz: a1b5122e4700ae49500fbfc7b7c1060561e3a73cdfe3c980f946453c54eac0fa0c0982914b2ffcb3a18710d9e5c4fddb0cc7b6a12f18feca424d64067987691d
7
- data.tar.gz: 4b4183d21184e1986ca78158f7d6e99aae06ea6767292448ddb1bc29b00f3fe2862000d9c642eb8b8c84e4ce19166778a5fa5e3439cdac1c33e925d2f0ce988f
6
+ metadata.gz: c12bd80a362e62935a333d6c9b3df3e8bee0618cb29ef3f0a3677d50b4a33b79a66a09e42b38b3ca2a72cb15c2fdef5542d08a4b190f03ce270ed35ce0d951e4
7
+ data.tar.gz: f0a9ea3a170fff1bab99b583d7c5cc491740ffec9b8f48f6de8eee29bc497c77a7d28db34f49b53e08ee49957a3601c4b37be074a4f2a9a7ee1e427fca5df5a8
@@ -139,10 +139,10 @@ module ForestLiana
139
139
 
140
140
  next if !should_include_attr?(attribute_name, attr_data)
141
141
 
142
- unless relation.polymorphic?
142
+ unless relation.nil? || (relation.respond_to?(:polymorphic?) && relation.polymorphic?)
143
143
  relation_class_name = ForestLiana.name_for(relation.klass).demodulize
144
144
 
145
- if object.send(relation.foreign_key.to_sym) &&
145
+ if object.respond_to?(relation.foreign_key.to_sym) &&
146
146
  @options[:fields][relation_class_name]&.size == 1 &&
147
147
  @options[:fields][relation_class_name]&.include?(relation.klass.primary_key.to_sym)
148
148
 
@@ -47,6 +47,8 @@ module ForestLiana
47
47
  end
48
48
 
49
49
  def separate_database?(resource, association)
50
+ return false if SchemaUtils.polymorphic?(association)
51
+
50
52
  target_model_connection = association.klass.connection
51
53
  target_model_database = target_model_connection.current_database if target_model_connection.respond_to? :current_database
52
54
  resource_connection = resource.connection
@@ -56,10 +56,22 @@ module ForestLiana
56
56
 
57
57
  def records
58
58
  records = @records.offset(offset).limit(limit).to_a
59
-
60
59
  polymorphic_association, preload_loads = analyze_associations(@resource)
61
- if polymorphic_association && Rails::VERSION::MAJOR >= 7
62
- # TODO
60
+
61
+ if polymorphic_association.any? && Rails::VERSION::MAJOR >= 7
62
+ preloader = ActiveRecord::Associations::Preloader.new(records: records, associations: polymorphic_association)
63
+ preloader.loaders
64
+ preloader.branches.each do |branch|
65
+ branch.loaders.each do |loader|
66
+ records_by_owner = loader.records_by_owner
67
+ records_by_owner.each do |record, association|
68
+ record_index = records.find_index { |r| r.id == record.id }
69
+ records[record_index].define_singleton_method(branch.association) do
70
+ association.first
71
+ end
72
+ end
73
+ end
74
+ end
63
75
  end
64
76
 
65
77
  preload_cross_database_associations(records, preload_loads)
@@ -73,7 +85,6 @@ module ForestLiana
73
85
  next unless separate_database?(@resource, association)
74
86
 
75
87
  columns = columns_for_cross_database_association(association_name)
76
-
77
88
  if association.macro == :belongs_to
78
89
  foreign_key = association.foreign_key
79
90
  primary_key = association.klass.primary_key
@@ -113,27 +124,22 @@ module ForestLiana
113
124
  end
114
125
 
115
126
  def columns_for_cross_database_association(association_name)
116
- return [:id] unless @params[:fields].present?
117
-
118
- fields = @params[:fields][association_name.to_s]
119
- return [:id] unless fields
120
-
121
- base_fields = fields.split(',').map(&:strip).map(&:to_sym) | [:id]
122
-
123
127
  association = @resource.reflect_on_association(association_name)
124
- extra_key = association.foreign_key
125
128
 
126
- # Add the foreign key used for the association to ensure it's available in the preloaded records
127
- # This is necessary for has_one associations, without it calling record.public_send(foreign_key) would raise a "missing attribute" error
128
- base_fields << extra_key if association.macro == :has_one
129
+ # Always include all columns of the associated model to avoid missing attribute errors
130
+ columns = association.klass.column_names.map(&:to_sym)
129
131
 
130
- base_fields.uniq
132
+ # Ensure the foreign key is present for manual binding (especially for has_one)
133
+ columns << association.foreign_key.to_sym if association.macro == :has_one
134
+
135
+ columns.uniq
131
136
  end
132
137
 
133
138
  def compute_includes
134
139
  associations_has_one = ForestLiana::QueryHelper.get_one_associations(@resource)
140
+
135
141
  @optional_includes = []
136
- if @field_names_requested
142
+ if @field_names_requested && @params['searchExtended'].to_i != 1
137
143
  includes = associations_has_one.map do |association|
138
144
  association_name = association.name.to_s
139
145
 
@@ -163,7 +169,10 @@ module ForestLiana
163
169
 
164
170
  @includes = (includes & @field_names_requested).concat(includes_for_smart_search)
165
171
  else
166
- @includes = associations_has_one.map(&:name)
172
+ @includes = associations_has_one
173
+ # Avoid eager loading has_one associations pointing to a different database as ORM can't join cross databases
174
+ .reject { |association| separate_database?(@resource, association) }
175
+ .map(&:name)
167
176
  end
168
177
  end
169
178
 
@@ -278,7 +278,13 @@ module ForestLiana
278
278
  field[:field] = association.name
279
279
  field[:inverse_of] = inverse_of(association)
280
280
  field[:relationship] = get_relationship_type(association)
281
- # NOTICE: Create the fields of hasOne, HasMany, … relationships.
281
+
282
+ ForestLiana::SchemaUtils.disable_filter_and_sort_if_cross_db!(
283
+ field,
284
+ association.name.to_s,
285
+ ForestLiana.name_for(@model)
286
+ )
287
+ # NOTICE: Create the fields of hasOne, HasMany, … relationships.
282
288
  else
283
289
  collection.fields << get_schema_for_association(association)
284
290
  end
@@ -346,7 +352,7 @@ module ForestLiana
346
352
  end
347
353
 
348
354
  def get_schema_for_association(association)
349
- {
355
+ opts ={
350
356
  field: association.name.to_s,
351
357
  type: get_type_for_association(association),
352
358
  relationship: get_relationship_type(association),
@@ -363,6 +369,14 @@ module ForestLiana
363
369
  widget: nil,
364
370
  validations: []
365
371
  }
372
+
373
+ ForestLiana::SchemaUtils.disable_filter_and_sort_if_cross_db!(
374
+ opts,
375
+ association.name.to_s,
376
+ ForestLiana.name_for(@model)
377
+ )
378
+
379
+ opts
366
380
  end
367
381
 
368
382
  def get_relationship_type(association)
@@ -126,5 +126,27 @@ module ForestLiana
126
126
  def self.is_active_type? model
127
127
  Object.const_defined?('ActiveType::Object') && model < ActiveType::Object
128
128
  end
129
+
130
+ def self.disable_filter_and_sort_if_cross_db!(opts, name, collection_name)
131
+ return unless opts[:reference]
132
+
133
+ assoc_name = opts[:reference].split('.').first&.underscore&.to_sym || name
134
+ model = find_model_from_collection_name(collection_name)
135
+ return unless model
136
+
137
+ association = model.reflect_on_association(assoc_name)
138
+ return unless association
139
+ return if polymorphic?(association)
140
+
141
+ model_db = model.connection_db_config.database
142
+ assoc_db = association.klass.connection_db_config.database
143
+
144
+ if model_db != assoc_db
145
+ opts[:is_filterable] = false
146
+ opts[:is_sortable] = false
147
+ end
148
+ rescue => e
149
+ FOREST_LOGGER.warn("Could not evaluate cross-db association for #{name}: #{e.message}")
150
+ end
129
151
  end
130
152
  end
@@ -1,3 +1,3 @@
1
1
  module ForestLiana
2
- VERSION = "9.14.0"
2
+ VERSION = "9.14.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: forest_liana
3
3
  version: !ruby/object:Gem::Version
4
- version: 9.14.0
4
+ version: 9.14.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sandro Munda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-05-26 00:00:00.000000000 Z
11
+ date: 2025-06-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails