Methods
A
C
P
R
S
T
U
W
Instance Public methods
assoc_from_sym(sym)
   # File rhino/rhino/lib/rhino/resource/active_record_extension/params.rb
31 def assoc_from_sym(sym)
32   reflect_on_association(sym).klass
33 end
create_params()
   # File rhino/rhino/lib/rhino/resource/active_record_extension/params.rb
10 def create_params
11   writeable_params("create")
12 end
props_by_type(type)
   # File rhino/rhino/lib/rhino/resource/active_record_extension/params.rb
35 def props_by_type(type)
36   # FIXME: Direct attributes for this model we want a copy, not to
37   # alter the class_attribute itself
38   send("#{type}_properties").dup
39 end
readable_params(type, refs = references)
   # File rhino/rhino/lib/rhino/resource/active_record_extension/params.rb
41 def readable_params(type, refs = references) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
42   params = []
43 
44   refs_index = refs.index_by { |r| reference_to_sym(r) }
45 
46   props_by_type("read").each do |prop|
47     desc = describe_property(prop)
48     prop_sym = prop.to_sym
49 
50     # If its a reference or an array of references
51     # FIXME: anyOf is a hack for now
52     if desc[:type] == :reference || (desc[:type] == :array && (desc[:items].key?(:$ref) || desc[:items].key?(:anyOf)))
53       next unless refs_index.key?(prop_sym)
54 
55       next_refs = refs_index[prop_sym].is_a?(Hash) ? refs_index[prop_sym][prop_sym] : []
56       assoc = assoc_from_sym(prop_sym)
57 
58       next params << { prop.to_s => assoc.send("readable_params", type, next_refs) }
59     end
60 
61     # JSON columns need special handling - allow all the nested params
62     next params << { prop => {} } if desc[:type].in?(%i[json jsonb])
63 
64     # Generic array of scalars
65     next params << { prop => [] } if desc[:type] == :array
66 
67     # Otherwise prop and param are equivalent
68     params << prop
69   end
70 
71   # Display name is always allowed
72   params << "display_name"
73 end
reference_to_sym(reference)
   # File rhino/rhino/lib/rhino/resource/active_record_extension/params.rb
27 def reference_to_sym(reference)
28   reference.is_a?(Hash) ? reference.keys.first : reference
29 end
show_params()
   # File rhino/rhino/lib/rhino/resource/active_record_extension/params.rb
14 def show_params
15   readable_params("show")
16 end
transform_params(params)
   # File rhino/rhino/lib/rhino/resource/active_record_extension/params.rb
22 def transform_params(params)
23   transform_params_recursive(params)
24 end
transform_params_recursive(params, parent = self)

Rebuild the params rubocop:todo Metrics/CyclomaticComplexity

    # File rhino/rhino/lib/rhino/resource/active_record_extension/params.rb
141 def transform_params_recursive(params, parent = self) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity
142   hash = {}
143   params.each do |param_key, param_value|
144     association = parent.reflect_on_association(param_key)
145 
146     # Its a regular attribute
147     next hash[param_key] = param_value unless association
148 
149     # FIXME
150     # Hack to rewrite for attachment/attachments and guard against object resubmission
151     if param_key.end_with?("_attachment")
152       hash[param_key.remove("_attachment")] = param_value if param_value.is_a?(String) || param_value.nil?
153 
154       next
155     end
156     if param_key.end_with?("_attachments")
157       hash[param_key.remove("_attachments")] = param_value if param_value.is_a?(Array) || param_value.nil?
158 
159       next
160     end
161 
162     # Transform the nested attributes as well
163     # Nested need _attributes - we don't want the client to have to do that
164     if parent.nested_attributes_options.key?(param_key.to_sym)
165       attr_key = "#{param_key}_attributes"
166 
167       # has_many nested should be an array
168       if association.macro == :has_many
169         next hash[attr_key] = param_value.map { |pv| parent.transform_params_recursive(pv, association.klass) }
170       end
171 
172       # has_one/belongs_to is just the values
173       # if its a cardinal though, such as blog: 1 instead of blog: {name : 'my blog' }
174       # fallback to transforming to the foreign key
175       if param_value.is_a?(ActionController::Parameters)
176         next hash[attr_key] = parent.transform_params_recursive(param_value, association.klass)
177       end
178     end
179 
180     # Map association name to foreign key, ie blog => blog_id
181     # or blog: { id: } => blog_id
182     if param_value.is_a?(ActionController::Parameters)
183       next hash[association.foreign_key] = param_value[association.klass.identifier_property]
184     end
185 
186     hash[association.foreign_key] = param_value
187   end
188 
189   # Force permit since we should have already been permitted at this point
190   ActionController::Parameters.new(hash).permit!
191 end
update_params()
   # File rhino/rhino/lib/rhino/resource/active_record_extension/params.rb
18 def update_params
19   writeable_params("update")
20 end
writeable_params(type, _refs = references)
    # File rhino/rhino/lib/rhino/resource/active_record_extension/params.rb
 75 def writeable_params(type, _refs = references) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
 76   params = []
 77 
 78   props_by_type(type).each do |prop|
 79     desc = describe_property(prop)
 80     prop_sym = prop.to_sym
 81 
 82     # An array of references
 83     if desc[:type] == :array && (desc[:items].key?(:$ref) || desc[:items].key?(:anyOf))
 84       # FIXME: Hack for has_many_attached
 85       next params << { prop => [] } if desc.dig(:items, :anyOf)[0]&.dig(:$ref) == "#/components/schemas/active_storage_attachment"
 86 
 87       # We only accept if the active record accepts it
 88       next unless nested_attributes_options.key?(prop_sym) || desc.dig(:items, :anyOf)[0]&.dig(:$ref)
 89 
 90       assoc = assoc_from_sym(prop_sym)
 91 
 92       # This does not handle nested for a polymorphic model, but neither does rails
 93       # FIXME: Do we need to handle :update_only option?
 94       # FIXME: If a nested resource attribute is create only, the backend will allow it to be
 95       # updated because create/update are merged together - the frontedn UI shows the right
 96       # thing though NUB-844
 97       assoc_params = []
 98 
 99       array_attributes = desc[:items][:"x-rhino-attribute-array"]
100 
101       if array_attributes[:updatable]
102         # If the attribute is updatable, we need to accept the id param
103         assoc_params << assoc.identifier_property
104 
105         # If the attribute is updatable, we need to accept its updatable params
106         assoc_params << assoc.send("writeable_params", "update")
107       end
108 
109       # If the attribute is creatable, we need to accept its creatable params
110       assoc_params << assoc.send("writeable_params", "create") if array_attributes[:creatable]
111 
112       # If its destroyable, accept the _destroy param
113       assoc_params << "_destroy" if nested_attributes_options[prop_sym][:allow_destroy]
114 
115       next params << { prop => assoc_params.flatten.uniq }
116     end
117 
118     # JSON columns need special handling - allow all the nested params
119     next params << { prop => {} } if desc[:type].in?(%i[json jsonb])
120 
121     # Generic array of scalars
122     next params << { prop => [] } if desc[:type] == :array
123 
124     # Accept { blog_post: { :id }} as well as { blog_post: 3 } below
125     if desc[:type] == :reference
126       assoc = assoc_from_sym(prop_sym)
127 
128       params << { prop => [assoc.identifier_property] }
129     end
130 
131     # Otherwise prop and param are equivalent
132     # We also accept the ref name as the foreign key if its a singular resource
133     params << prop
134   end
135 
136   params
137 end