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 +4 -4
- data/app/controllers/forest_liana/application_controller.rb +12 -1
- data/app/serializers/forest_liana/serializer_factory.rb +120 -0
- data/app/services/forest_liana/resources_getter.rb +0 -46
- data/lib/forest_liana/version.rb +1 -1
- data/spec/requests/resources_spec.rb +1 -12
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 01b3a5629878eddd5cfdeea4bcb0fadcdd46c5211ac3bf327d8cda5cc6ecb068
|
4
|
+
data.tar.gz: a05b24374ac64efca265824dcd69167c690b1a7bff67fbafc06ab9d497fa2531
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
|
data/lib/forest_liana/version.rb
CHANGED
@@ -124,18 +124,7 @@ describe 'Requesting Tree resources', :type => :request do
|
|
124
124
|
"included" => [{
|
125
125
|
"type" => "Location",
|
126
126
|
"id" => "1",
|
127
|
-
"
|
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.
|
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-
|
11
|
+
date: 2025-08-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|