Rails 5 (don't know about the others) comes with an initializer wrap_parameters.rb
. Here you can tell rails to wrap parameters send to your controllers for specific formats into a root node which it guesses from the controller name.
ActiveSupport.on_load(:action_controller) do
wrap_parameters format: [:json]
end
This would wrap a flat json body, like
{"name": "Konata"}
that gets send to your UsersController
into
{"name" => "Konata", "user" => {"name" => "Konata"}}
Note that the params are now duplicated though! That does not need to disturb you. With strong params you can now simply fetch the params for the company by saying
params.require(:user).permit(*MODEL_ATTRIBUTES)
Just like you are used to when you are dealing with form payloads. This is especially handy because Rails puts some stuff in the params which does not really belong there IMHO. For instance there is a :format
parameter that comes in the way when you configure strong params to raise on unpermitted params and you try to permit only your model attributes on the flat params hash.
You can also overwrite these settings for your controller. Below you can also see how to set the key that the params will be wrapped into.
class UsersController < ApplicationController
wrap_parameters :person, include: [:username, :password]
end
And there is more! Check the attached link for other features ...
Note: When you use Form Models you need to add virtual attributes manually. E.g.
wrap_parameters include: User.attribute_names + ['send_email']