-
Notifications
You must be signed in to change notification settings - Fork 164
require returns Array then errors followed by permit #140
Comments
This is a duplicate of #139. |
Hi @KevinSjoberg @rafaelfranca , it looks similar, but my issue's title is better for searching. As the issue is on the require method: def require(key)
self[key].presence || raise(ActionController::ParameterMissing.new(key))
end Which returns the value instead of returning the ActionController::Parameters instance. So it will never works for calling any other ActionController::Parameters instance method like permit. Therefore the README and API is wrong and has to be updated |
This problem only occurs when the value of the key is an Array, so yes, the README should be update to say that require only works when the value of the key is a hash. |
Thx @rafaelfranca for the reply, But I am afraid it is not working at all as long as it doesn't return the ActionController::Parameters instance. irb(main):002:0> raw_parameters = { :teams => "37" }
=> {:teams=>"37"}
irb(main):003:0> parameters = ActionController::Parameters.new(raw_parameters)
=> {"teams"=>"37"}
irb(main):004:0> parameters.require(:teams).permit!
NoMethodError: undefined method `permit!' for "37":String It would be good that if you could provide an example that actually works. Thx. |
No, it only work if the value is a hash. This should work:
|
IC, cool. Thank you very much @rafaelfranca. Once README updated then it's all good 👍 😄 |
Running into the same issue as I look to introduce strong_parameters to my JSON rails-api. Typical request JSON as seen in the examples at jsonapi.org looks something like this: {"cards":[{"subject":"some subject", "reference":"some reference"}] } Note the array mixed into this. If I start my strong_parameters statement with something like params.require(:cards), I get back an Array, not an instance of ActionController::Parameters, and even accepting that, if I go through each array member, they are not ActionController::Parameters instances either (they are instances of ActiveSupport::HashWithIndifferentAccess). |
👍 on strong_parameters with a JSON API like @wrwright. Even if I don't want to allow an array, this is allows user input to cause NoMethod Errors and return a 500, when really this is probably a 400 or 422. Aside from rescuing from NoMethod and matching on the error message, there is no good way to gracefully recover from bad user input. What if we ensured that the require returned the proper type or responded to Thoughts? I can make a pull request if we like it. |
Currently I'm solving these issues by iterating over the array and manually |
@KevinSjoberg I guess my issue is more that I don't want the array, or anything in it, but it is valid JSON and I may receive it from a client request. I would think the response should be a 4xx rather than a 500. |
Alternatively, I've implemented this in my API specific application controller: rescue_from NoMethodError do |exception|
if exception.message =~ /undefined method `permit' for/
render json: { message: "Helpful error message..." }, status: :bad_request
else
raise
end
end |
@wrightling that's how I do it, maybe it may be still useful to you :) json-api/json-api#121 (comment) def create
photos = []
photo_params.each do |p|
photo = Photo.new(p)
photos << photo if photo.save
end
render json: photos, status: 201
end
def photo_params
params.require(:photos).map do |p|
ActionController::Parameters.new(p.to_hash).permit(:title, :src)
end
end |
@vdmgolub |
@guy-silva and I ran into this dealing with Mandrill inbound webhooks params = ActionController::Parameters.new({
mandrill_events: [
{
msg: {
name: 'Francesco',
age: 22,
role: 'admin'
}
},
{
msg: {
name: 'steve',
age: 22,
role: 'admin'
}
}
]
})
permitted = params.require(:mandrill_events).map { |m| m.require(:msg).permit(:name, :age) }
# => [{"name"=>"Francesco", "age"=>22}, {"name"=>"steve", "age"=>22}] |
@vdmgolub |
It's honestly so much easier to do
and just not chain them. |
@ryanmtaylor I am getting ActiveModel::ForbiddenAttributesError (ActiveModel::ForbiddenAttributesError). Error log:ActiveModel::ForbiddenAttributesError (ActiveModel::ForbiddenAttributesError): app/controllers/traumas_controller.rb:28:in I did as per your suggestion as below. stdout output:Started POST "/traumas/create_multiple" for 127.0.0.1 at 2016-10-05 14:38:49 +0530 Controller method:
|
Resolved by referring @vdmgolub code. |
From Readme:
In my console:
Looks like the Readme needs to update with the correct API
The text was updated successfully, but these errors were encountered: