Skip to content

Commit a173f43

Browse files
committed
fix(serializer): override find_recursive_relationships
1 parent 672dbeb commit a173f43

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed

app/serializers/forest_liana/serializer_factory.rb

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,81 @@ def self.get_serializer_name(active_record_class)
4747
end
4848
end
4949

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+
50125
def initialize(is_smart_collection = false)
51126
@is_smart_collection = is_smart_collection
52127
end
@@ -158,6 +233,24 @@ def has_one_relationships
158233
data
159234
end
160235

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+
161254
private
162255

163256
def intercom_integration?

0 commit comments

Comments
 (0)