I'm having problems trying to implement a PATCH endpoint for a Rails API which deals with complex request objects that are structurally different from the ActiveRecord model.
As an example let's say I have the following request object:
{
"details": {
"color": {
"id": 1
}
},
"name": "Hello, world!"
...
}
However, on my model I expect a flat color_id attribute:
class CreateModel < ActiveRecord::Migration[7.0]
def change
create_table :model do |t|
t.string :name, null: false
t.integer :color_id, null: false
end
end
end
Therefore I need to transform the request params. For this I've found one approach which works pretty well in case of PUT requests, but not at all for PATCH:
ActionController::Parameters.new({
color_id: params.dig(:details, :color, :id),
name: params.dig(:name)
})
If I issue a PUT request this solution works great since PUT expects the whole object as payload, PATCH on the other hand would cause issues when passing only a subset of the properties since everything else will be set to nil due to how dig works.
Assuming I have no control over the request format, how can I transform the request params in the backend so that omitted keys will not result in nil values? Of course I could imperatively handle each property line by line, checking whether the key is present in the original params and then setting it in the new one, but is there a more elegant approach?