In Rails 4 here is the question about HOW to do this. What I would like to know is, although this works, WHY does the log still complain?
In Rails 5.1.3 I have a JSON column (letterhead
) as one of my model attributes (and inside that json is a hash with various attributes that I don't care about whitelisting). I just want to permit/whitelist the column itself.
Note on Rails 5.1.4
There is a Rails way to do this in 5.1.4, see this commit. There is a rather long discussion here on github about this. In Rails 5.1.4 it is simply this:
def account_params
params.require(:account).permit(:id, :name, :plan_id, letterhead: {})
end
The :letterhead
parameter is permitted, no error shows in the log and the model saves. But obviously it allows arbitrary input inside that parameter, so use with care.
If you did want to restrict which hash keys were allowed inside such a parameter, then you can also whitelist those, like this for example:
def account_params
params.require(:account).permit(:id, :name, :plan_id, letterhead: [:address, :logo, :contact_info])
end
This now prevents any other arbitrary keys inside :letterhead
since I have explicitly only permitted these 3 - :address, :logo, :contact_info
Rails 5.1.3 (and earlier)
I can permit this column using either of the following (see the linked discussion for other possible options also):
Option 1
def account_params
params.require(:account).permit(:id, :name, :plan_id, :letterhead).tap do |whitelisted|
whitelisted[:letterhead] = params[:account].fetch(:letterhead, ActionController::Parameters.new).permit!
end
end
Option 2
def account_params
params.require(:account).permit(:id, :name, :plan_id, :letterhead).tap do |whitelisted|
whitelisted[:letterhead] = params[:account][:letterhead].permit!
end
end
In both cases the model saves but in the log it still says "unpermitted parameters :letterhead"
Why is still saying that when I have explicitly permitted it?
Also, is there any real difference between Option 1 and Option 2?
EDIT
Data is like this:
{"id"=>"a61151b8-deed-4efa-8cad-da1b143196c9",
"plan_id"=>"1dc49acf-3111-4030-aea1-7db259b53a51",
"name"=>"Test Account 1",
"is_active"=>true,
"letterhead"=>{"left"=>"", "center"=>"", "right"=>""},
"created_by"=>nil,
"updated_by"=>nil,
"created_at"=>"2017-10-14T19:05:40.197Z",
"updated_at"=>"2017-10-20T15:14:08.194Z"}
The log comes from #unpermitted_parameters!
which is called by #permit
. All this happens before the call to #tap
.
The difference boils down to
params[:account].fetch(:letterhead, ActionController::Parameters.new).permit!
vs
params[:account][:letterhead].permit!
The latter will result in NoMethodError
if :letterhead
isn't passed because params[:account][:letterhead]
will return nil
. The former returns an empty hash of parameters instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With