forest_liana 9.15.2 → 9.15.4

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: 1d472c9569d143414f26b2f574fb1a645eabb4cae94ada16510ea776609d78e7
4
- data.tar.gz: d5ec3a959fea0e578abdd8667ec2c062e125aa663e241b27834ad668effa74c7
3
+ metadata.gz: 01b3a5629878eddd5cfdeea4bcb0fadcdd46c5211ac3bf327d8cda5cc6ecb068
4
+ data.tar.gz: a05b24374ac64efca265824dcd69167c690b1a7bff67fbafc06ab9d497fa2531
5
5
  SHA512:
6
- metadata.gz: e804289358deb668cab2b0dcd23027a18b0cc67fa27a490ae7cb405ef62c29a269df58f6d9692651782dce51c41ae09dcbf692686cdeea8dc4e0f22165a37334
7
- data.tar.gz: 4ff713e235b574d038af42d11f6e84c6e56a9cca6dfd738f432cf16259a64cd8a1059b97f4923a0304b19b2f1cea15cb32d066c868889494b9f16d38ebe69c33
6
+ metadata.gz: 89fcfaf157e5cc76277e85eba8ad01ba92450e8f9081a8602881ae5d7b20bdd23e11b0029ad144000b7b886f081d2f5f0a7444084990df1678a44d471dd94fd8
7
+ data.tar.gz: b02ae1262881d03d225f7795e92e26764a738343ba8880b36ed13d44521a3d09686db209dda8a4ecfa260afe3990859ee2eff348892f74891d7e60b11791fcd1
@@ -40,6 +40,8 @@ module ForestLiana
40
40
 
41
41
  def serialize_model(record, options = {})
42
42
  options[:is_collection] = false
43
+ options[:context] = { unoptimized: true }.merge(options[:context] || {})
44
+
43
45
  json = ForestAdmin::JSONAPI::Serializer.serialize(record, options)
44
46
 
45
47
  force_utf8_encoding(json)
@@ -156,10 +158,12 @@ module ForestLiana
156
158
  params_fields_hash.inject({}) do |fields, param_field|
157
159
  relation_name = param_field[0]
158
160
  relation_fields = param_field[1]
161
+ forest_collection = ForestLiana.apimap.find { |collection| collection.name.to_s == model.to_s.gsub('::', '__') }
162
+ smart_relations = forest_collection.fields_smart_belongs_to
159
163
 
160
164
  if relation_name == ForestLiana.name_for(model)
161
165
  fields[relation_name] = relation_fields
162
- else
166
+ elsif model.reflect_on_association(relation_name.to_sym)
163
167
  model_association = model.reflect_on_association(relation_name.to_sym)
164
168
  if model_association
165
169
  model_name = ForestLiana.name_for(model_association.klass)
@@ -173,7 +177,14 @@ module ForestLiana
173
177
  fields[model_name] = relation_fields
174
178
  end
175
179
  end
180
+ else
181
+ smart_relations.each do |smart_relation|
182
+ if smart_relation[:field].to_s == relation_name
183
+ fields[relation_name] = relation_fields
184
+ end
185
+ end
176
186
  end
187
+
177
188
  fields
178
189
  end
179
190
  else
@@ -47,6 +47,81 @@ module ForestLiana
47
47
  end
48
48
  end
49
49
 
50
+ # duplicate method from Serializer
51
+ ForestAdmin::JSONAPI::Serializer.singleton_class.send(:define_method, :find_recursive_relationships) do |root_object, root_inclusion_tree, results, options|
52
+ ActiveSupport::Notifications.instrument(
53
+ 'render.jsonapi_serializers.find_recursive_relationships',
54
+ {class_name: root_object.class.name},
55
+ ) do
56
+ root_inclusion_tree.each do |attribute_name, child_inclusion_tree|
57
+ next if attribute_name == :_include
58
+
59
+ serializer = ForestAdmin::JSONAPI::Serializer.find_serializer(root_object, options)
60
+ unformatted_attr_name = serializer.unformat_name(attribute_name).to_sym
61
+ object = nil
62
+ is_collection = false
63
+ is_valid_attr = false
64
+ if serializer.has_one_relationships.has_key?(unformatted_attr_name)
65
+ # only added this condition
66
+ if root_object.class.reflect_on_association(unformatted_attr_name)&.polymorphic?
67
+ options[:context][:unoptimized] = true
68
+ end
69
+
70
+ is_valid_attr = true
71
+ attr_data = serializer.has_one_relationships[unformatted_attr_name]
72
+ object = serializer.has_one_relationship(unformatted_attr_name, attr_data)
73
+ elsif serializer.has_many_relationships.has_key?(unformatted_attr_name)
74
+ is_valid_attr = true
75
+ is_collection = true
76
+ attr_data = serializer.has_many_relationships[unformatted_attr_name]
77
+ object = serializer.has_many_relationship(unformatted_attr_name, attr_data)
78
+ end
79
+
80
+ if !is_valid_attr
81
+ raise ForestAdmin::JSONAPI::Serializer::InvalidIncludeError.new(
82
+ "'#{attribute_name}' is not a valid include.")
83
+ end
84
+
85
+ if attribute_name != serializer.format_name(attribute_name)
86
+ expected_name = serializer.format_name(attribute_name)
87
+
88
+ raise ForestAdmin::JSONAPI::Serializer::InvalidIncludeError.new(
89
+ "'#{attribute_name}' is not a valid include. Did you mean '#{expected_name}' ?"
90
+ )
91
+ end
92
+
93
+ next if object.nil?
94
+
95
+ objects = is_collection ? object : [object]
96
+ if child_inclusion_tree[:_include] == true
97
+ objects.each do |obj|
98
+ obj_serializer = ForestAdmin::JSONAPI::Serializer.find_serializer(obj, options)
99
+ key = [obj_serializer.type, obj_serializer.id]
100
+
101
+ current_child_includes = []
102
+ inclusion_names = child_inclusion_tree.keys.reject { |k| k == :_include }
103
+ inclusion_names.each do |inclusion_name|
104
+ if child_inclusion_tree[inclusion_name][:_include]
105
+ current_child_includes << inclusion_name
106
+ end
107
+ end
108
+
109
+ current_child_includes += results[key] && results[key][:include_linkages] || []
110
+ current_child_includes.uniq!
111
+ results[key] = {object: obj, include_linkages: current_child_includes}
112
+ end
113
+ end
114
+
115
+ if !child_inclusion_tree.empty?
116
+ objects.each do |obj|
117
+ find_recursive_relationships(obj, child_inclusion_tree, results, options)
118
+ end
119
+ end
120
+ end
121
+ end
122
+ nil
123
+ end
124
+
50
125
  def initialize(is_smart_collection = false)
51
126
  @is_smart_collection = is_smart_collection
52
127
  end
@@ -131,6 +206,51 @@ module ForestLiana
131
206
  ret
132
207
  end
133
208
 
209
+ def has_one_relationships
210
+ return {} if self.class.to_one_associations.nil?
211
+ data = {}
212
+ self.class.to_one_associations.each do |attribute_name, attr_data|
213
+ relation = object.class.reflect_on_all_associations.find { |a| a.name == attribute_name }
214
+ next if !should_include_attr?(attribute_name, attr_data)
215
+
216
+ if relation && relation.belongs_to? && relation.polymorphic?.nil?
217
+ reflection_primary_key = relation.options[:primary_key]&.to_sym || :id
218
+ klass_primary_key = relation.klass.primary_key.to_sym
219
+
220
+ if reflection_primary_key != klass_primary_key
221
+ data[attribute_name] = attr_data.merge({
222
+ attr_or_block: proc {
223
+ relation.klass.find_by(reflection_primary_key => object.send(relation.foreign_key))
224
+ }
225
+ })
226
+ next
227
+ end
228
+ end
229
+
230
+ data[attribute_name] = attr_data
231
+ end
232
+
233
+ data
234
+ end
235
+
236
+ def should_include_attr?(attribute_name, attr_data)
237
+ collection = self.type
238
+
239
+ unless @options.dig(:context, :unoptimized)
240
+ return false unless @options[:fields][collection]&.include?(attribute_name.to_sym)
241
+ end
242
+
243
+ # Allow "if: :show_title?" and "unless: :hide_title?" attribute options.
244
+ if_method_name = attr_data[:options][:if]
245
+ unless_method_name = attr_data[:options][:unless]
246
+ formatted_attribute_name = format_name(attribute_name).to_sym
247
+ show_attr = true
248
+ show_attr &&= send(if_method_name) if if_method_name
249
+ show_attr &&= !send(unless_method_name) if unless_method_name
250
+ show_attr &&= @_fields[type.to_s].include?(formatted_attribute_name) if @_fields[type.to_s]
251
+ show_attr
252
+ end
253
+
134
254
  private
135
255
 
136
256
  def intercom_integration?
@@ -74,55 +74,9 @@ module ForestLiana
74
74
  end
75
75
  end
76
76
 
77
- preload_cross_database_associations(records, preload_loads)
78
-
79
77
  records
80
78
  end
81
79
 
82
- def preload_cross_database_associations(records, preload_loads)
83
- preload_loads.each do |association_name|
84
- association = @resource.reflect_on_association(association_name)
85
- next unless separate_database?(@resource, association)
86
-
87
- columns = columns_for_cross_database_association(association_name)
88
- if association.macro == :belongs_to
89
- foreign_key = association.foreign_key
90
- primary_key = association.klass.primary_key
91
-
92
- ids = records.map { |r| r.public_send(foreign_key) }.compact.uniq
93
- next if ids.empty?
94
-
95
- associated = association.klass.where(primary_key => ids)
96
- .select(columns)
97
- .index_by { |record| record.public_send(primary_key) }
98
-
99
- records.each do |record|
100
- record.define_singleton_method(association_name) do
101
- associated[record.send(foreign_key.to_sym)] || nil
102
- end
103
- end
104
- end
105
-
106
- if association.macro == :has_one
107
- foreign_key = association.foreign_key
108
- primary_key = association.active_record_primary_key
109
-
110
- ids = records.map { |r| r.public_send(primary_key) }.compact.uniq
111
- next if ids.empty?
112
-
113
- associated = association.klass.where(foreign_key => ids)
114
- .select(columns)
115
- .index_by { |record| record.public_send(foreign_key.to_sym) }
116
-
117
- records.each do |record|
118
- record.define_singleton_method(association_name) do
119
- associated[record.send(primary_key.to_sym)] || nil
120
- end
121
- end
122
- end
123
- end
124
- end
125
-
126
80
  def columns_for_cross_database_association(association_name)
127
81
  association = @resource.reflect_on_association(association_name)
128
82
 
@@ -1,3 +1,3 @@
1
1
  module ForestLiana
2
- VERSION = "9.15.2"
2
+ VERSION = "9.15.4"
3
3
  end
@@ -124,18 +124,7 @@ describe 'Requesting Tree resources', :type => :request do
124
124
  "included" => [{
125
125
  "type" => "Location",
126
126
  "id" => "1",
127
- "attributes" => include(
128
- "id" => 1,
129
- "created_at" => nil,
130
- "updated_at" => nil,
131
- "coordinates" => nil
132
- ),
133
- "links" => { "self" => "/forest/location/1" },
134
- "relationships" => {
135
- "island" => {
136
- "links" => { "related" => {} }
137
- }
138
- }
127
+ "links" => { "self" => "/forest/location/1" }
139
128
  }]
140
129
  })
141
130
  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.15.2
4
+ version: 9.15.4
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-07-24 00:00:00.000000000 Z
11
+ date: 2025-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails