Rails 5 Permitting controller action changed params - ruby-on-rails

So i have the following params permitted.
p = params.permit(:a, :b, :c, :lines => [:location_id, :quantity, :product => [:id]])
In my controller action, i add to the lines param the data i've permitted.
p['lines'] << {"product"=>{"id"=>"123456"}, "quantity"=>"2", "location_id"=>"123456"}
This is how the params looked after they've been changed.
puts params['lines']
#> [<ActionController::Parameters {"product"=>{"id"=>"123456"}, "quantity"=>"2", "location_id"=>"123456"} permitted: false>]
But as you can see it's not permitted. What am i missing here? I am using Rails 5.

To get permitted (whitelisted) params, you always have to make sure that you call the permitted version, p in your case, whenever params changes.
The difference between params and p is that params.permit(...) returns a permitted copy of itself and assigns it to p. So params permission state remains unchanged.
Try with puts p['lines'] instead of puts params['lines'] to see if you get the desired result.

Related

attr_accessor returns nil in model while returns the correct value in the controller

I have a model Assignment with attr_accessor :members
When I send my ajax request I can see in the terminal the params that are passed, and the my attr_accessor is well set "members"=>["", "12", "13"]
Here is an overview:
Parameters: {"utf8"=>"✓",
"authenticity_token"=>"YfDZ8VHrrriXLgf2RRHdZtzE8X0V5NFrEOBKZmoCw5mbvqbNKBsUVdBeJSY6HCj4YqcTQi2iiYZFhXx3SYFngw==",
"assignment"=>{"members"=>["", "12", "13"], ....}
However in my model Assignment the value of members accessor returns always nil :
before_validation :check_members
def check_members
throw self.members # this throws: UncaughtThrowError (uncaught throw nil)
end
Why am getting nil for members instead the array of values ?
It seems that I needed to specify an "empty array" for the strong parameters, What I had before is this :
params.require(:assignment).permit(:title, :members)
I turned it to
params.require(:assignment).permit(:title, :members => [])
Now it's working :)
A related source : how to permit an array with strong parameters

Accessing value(s) of ActionController Parameters hash

I'm having trouble with parameters in an app upgraded from 4.2 to 5.1. I have permitted my parameters, but as the documentation states, I'm getting back an object for my hash array, but can't seem to access the values of it. How can I just get the value of this object?
{"_method"=>"delete", "authenticity_token"=>"Z6ZqriiuXu6ODDqhGgocGiaN12rjKD6pUB6n/2v+CABZDAjwLzwczsMM3nM8f0PI0nww43o5mlC35HK+9PVa8w==",
"domain_name"=>"test.testmodule2.com.",
"hosted_zone_id"=>"/hostedzone/XXXXXXXXXX",
"ttl"=>"3600",
"type"=>"A",
"value"=>[{"value"=>"1.1.1.1"}],
"id"=>"/hostedzone/XXXXXXXXXX"}
def record_params
params.permit!([:hosted_zone_id, :domain_name, :type, :ttl, :alias, :value]).to_h!
end
def destroy
value = params[:value]
# returns [<ActionController::Parameters {"value"=>"1.1.1.1"} permitted: true>]
# would like it to return [{"value"=>"1.1.1.1"}]
end
If that hash is the value of params[:value], then access the value key inside, like:
params[:value] = {
"_method"=>"delete",
"authenticity_token"=>"...",
"domain_name"=>"test.testmodule2.com.",
"hosted_zone_id"=>"/hostedzone/XXXXXXXXXX",
"ttl"=>"3600",
"type"=>"A",
"value"=>[{"value"=>"1.1.1.1"}],
"id"=>"/hostedzone/XXXXXXXXXX"
}
params['value']['value'][0]['value']
# => "1.1.1.1"
params['value']['value'][0].keys
# => ["value"]

strong_params removing id of accepts_nested_attributes_for models

I have the follow strong_params statement:
def product_grid_params
params.require(:product_grid).permit(:name,
product_grid_locations_attributes: [:id, :grid_index, :item_id, :item_type, :short_name, :long_name]
).merge({ venue_id: params[:venue_id] })
end
But my params and product_grid_params look like this:
(byebug) params
{"product_grid"=>{"product_grid_locations_attributes"=>[{"id"=>"5560d1f7a15a416719000007", "short_name"=>"shrt", "long_name"=>"Whiskey Ginger", "grid_index"=>73, "item_type"=>"product", "item_id"=>"9b97aa28-1349-4f60-a359-3907c8ac9a74"}]}, "id"=>"5560d1f7a15a416719000006", "venue_id"=>"5560d1f7a15a416719000005", "format"=>"json", "controller"=>"api/v2/manager/product_grids", "action"=>"update"}
(byebug) product_grid_params
{"product_grid_locations_attributes"=>[{"grid_index"=>73, "item_id"=>"9b97aa28-1349-4f60-a359-3907c8ac9a74", "item_type"=>"product", "short_name"=>"shrt", "long_name"=>"Whiskey Ginger"}], "venue_id"=>"5560d1f7a15a416719000005"}
You'll notice that in the params, the product_grid_location's id is present, but it gets filtered out in product_grid_params. What gives? I need that id there to update nested attributes.
Looks like this was because of an issue with Mongoid. The id I was passing in was a Moped::BSON::ObjectId, which strong_params refused to parse. I converted it to a string and everything was fine after that:
params[:product_grid][:product_grid_locations_attributes].each { |location| location[:id] = location[:id].to_str }

Rails 4 Unpermitted Parameters for Array

I have an array field in my model and I'm attempting to update it.
My strong parameter method is below
def post_params
params["post"]["categories"] = params["post"]["categories"].split(",")
params.require(:post).permit(:name, :email, :categories)
end
My action in my controller is as follows
def update
post = Post.find(params[:id]
if post and post.update_attributes(post_params)
redirect_to root_url
else
redirect_to posts_url
end
end
However, whenever I submit the update the post, in my development log I see
Unpermitted parameters: categories
The parameters passed through is
Parameters: {"utf8"=>"✓", "authenticity_token"=>"auth token", "id"=>"10",
"post"=>{"name"=>"Toni Mitchell", "email"=>"eileen_hansen#hayetokes.info", "categories"=>",2"}}
I want to think it has something to do with the fact that the attribute categories is an array since everything else looks fine. Then again, I could be wrong. So, what's wrong with my code and why is not letting me save the categories field when clearly it is permitted to do so? Thanks.
Try this
params.require(:post).permit(:name, :email, :categories => [])
(Disregard my comment, I don't think that matters)
in rails 4, that would be,
params.require(:post).permit(:name, :email, {:categories => []})
The permitted scalar types are String, Symbol, NilClass, Numeric, TrueClass, FalseClass, Date, Time, DateTime, StringIO, IO, ActionDispatch::Http::UploadedFile and Rack::Test::UploadedFile.
To declare that the value in params must be an array of permitted scalar values map the key to an empty array:
params.permit(:id => [])
This is what the strong parameters documentation on Github says:
params.require(:post).permit(:name, :email, :categories => [])
I hope this works out for you.
I had the same problem, but simply adding array to permit was not enough. I had to add type, too. This way:
params.require(:transaction).permit(:name, :tag_ids => [:id])
I am not sure if this is perfect solution, but after that, the 'Unpermitted parameters' log disappeared.
I found hint for that solution from this excellent post: http://patshaughnessy.net/2014/6/16/a-rule-of-thumb-for-strong-parameters
If there are multiple items and item_array inside parameters like this-
Parameters {"item_1"=>"value 1", "item_2"=> {"key_1"=> "value A1",
"key_2"=>["val B2", "val C3"]} }
There we have array inside item_2.
That can be permit as below-
params.permit(item_2: [:key_1, :key_2 => [] ])
Above saved my day, may be helpful for you too.
I had the same problem but in my case I had also to change from:
<input type="checkbox" name="photographer[attending]" value="Baku">
to:
<input type="checkbox" name="photographer[attending][]" value="Baku">
Hope this is helping someone.

Accessing a Hash in a REST POST

I have a hash in Ruby:
params={"username"=>"test"}
I want to add another associative array like:
params["user"]={"name"=>"test2"}
so params should become
params={"username"=>"test","user"=>{"name"=>"test2"}}
but when I post this params to a url, I get:
params[:user][:name] # => nil
when I dump the user data:
params[:user] # => ['name','test2']
what I want is
params[:user] # => output {'name'=>'test2'}
what am I doing wrong? thanks for help.
You're just using wrong key, you think that :user and "user" are the same, which is not.
params["user"]["name"] #=> "test2"
params["user"] #=> {"name"=>"test2"}
UPDATE from Naveed:
:user is an instance of Symbol class while "user" is instance of String
You have created a hash with keys of type string and trying to access with symbol keys. This works only with class HashWithIndifferentAccess.
If you want to achieve the same convert your hash to HashWithIndifferentAccess by using with_indifferent_access method,
> params = {"username"=>"test", "user"=>{"name"=>"test2"}}
=> {"username"=>"test", "user"=>{"name"=>"test2"}}
> params[:user][:name]
=> nil
>params = params.with_indifferent_access
> params[:user][:name]
=> "test2"
Update: request params is an instance of HashWithIndifferentAccess
The following should work:
params["user"]
params={"username"=>"test"}# params is not array nor associative array its a hash
you can add key value pair in hash by
params["key"]="value"
key and value both can be object of any class,be sure you use same object as key to access value or take a look at
HashWithIndifferentAccess
now
params["user"]={"name"=>"blah"}
params["user"] # => {"name"=>"blah"}
params["user"]["name"] # => "blah"

Resources