forest_liana 9.15.2 → 9.15.3
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 +10 -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: 6c293cc19d5273766a98fcc556bb07bcdd9dea63cd604aeee9352055556b9994
|
4
|
+
data.tar.gz: fe841959936a030dc0989da2645ce9db9a74237bf86d7028c2cc4c7de27fece8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4ab70690f0da9891d2e5484ad33548e443bf5d72cf0edbc24caae74fe6214a2e3d9f10489ebdb331b907809a6d19cd2cfdd1631c80ed5c0aff4156a5e666326
|
7
|
+
data.tar.gz: bb3272e7f6ae11f3538f15ac0cb280df67015ac940d1734d8cc5d04f9ad1168b1e09ad9073e3b85cfef0c936d7393db70a90973e14a34d0e367584e46f3a4311
|
@@ -156,10 +156,12 @@ module ForestLiana
|
|
156
156
|
params_fields_hash.inject({}) do |fields, param_field|
|
157
157
|
relation_name = param_field[0]
|
158
158
|
relation_fields = param_field[1]
|
159
|
+
forest_collection = ForestLiana.apimap.find { |collection| collection.name.to_s == model.to_s.gsub('::', '__') }
|
160
|
+
smart_relations = forest_collection.fields_smart_belongs_to
|
159
161
|
|
160
162
|
if relation_name == ForestLiana.name_for(model)
|
161
163
|
fields[relation_name] = relation_fields
|
162
|
-
|
164
|
+
elsif model.reflect_on_association(relation_name.to_sym)
|
163
165
|
model_association = model.reflect_on_association(relation_name.to_sym)
|
164
166
|
if model_association
|
165
167
|
model_name = ForestLiana.name_for(model_association.klass)
|
@@ -173,7 +175,14 @@ module ForestLiana
|
|
173
175
|
fields[model_name] = relation_fields
|
174
176
|
end
|
175
177
|
end
|
178
|
+
else
|
179
|
+
smart_relations.each do |smart_relation|
|
180
|
+
if smart_relation[:field].to_s == relation_name
|
181
|
+
fields[smart_relation[:reference].split('.').first] = relation_fields
|
182
|
+
end
|
183
|
+
end
|
176
184
|
end
|
185
|
+
|
177
186
|
fields
|
178
187
|
end
|
179
188
|
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.3
|
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-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|