nicolasblanco/rails_param

Wrong array to string coercion

Opened this issue · 4 comments

Basic Info

  • rails_param Version: 1.3.0
  • Ruby Version: 3.1
  • Rails Version: 7.0

Issue description

We pass in our spec the following:

req[:orders_attributes][0][:email] = %w[foo@bar.com baz@fuzz.com]

And in our controller we validate this param with a:

   order.param! :email, String

With rails_param (0.11.2) and rails 6 the coercion happens. With rails_param (~> 1.3.0) it doesn't

Extract from pry session while running the spec:

RAILS 6

[3] pry(#<Api::ImportController>)> order.params["email"]
=> ["foo@bar.com", "baz@fuzz.com"]
[4] pry(#<Api::ImportController>)> 

[3] pry(#<Api::ImportController>)> order.param! :email, String
RailsParam::Param::InvalidParameterError: '["foo@bar.com", "baz@fuzz.com"]' is not a valid String
from /home/foo/.bundle/ruby/3.1.0/gems/rails_param-0.11.2/lib/rails_param/param.rb:134:in `rescue in coerce'
Caused by ArgumentError: ArgumentError
from /home/foo/.bundle/ruby/3.1.0/gems/rails_param-0.11.2/lib/rails_param/param.rb:106:in `coerce'

RAILS 7 and the gem 1.3.0, the exception doesn't get raised

[1] pry(#<Api::ImportController>)> order.params["email"]
=> ["foo@bar.com", "baz@fuzz.com"]
[2] pry(#<Api::ImportController>)> order.param! :email, String
=> "[\"foo@bar.com\", \"baz@fuzz.com\"]"
[3] pry(#<Api::Las::Scc::ImportController>)> 

For sure in that case I could simply validate by format, but I have more than 30 unique fails, since this is validated in many different parameters.

Steps to reproduce

I think passing an array like %w[foo@bar.com baz@fuzz.com] or as nested attributes like in my case (req[:orders_attributes][0][:email] ) having he validation as foo.param! :email, String should do the trick:

Thank you for reporting this @vpereira and apologies for the slow reply.
Just to confirm: does the Rails version make any difference?
Am I right to understand rails_param 0.11.x works in both Rails 6/7, while rails_param 1.x fails for both?

I won't have time to look into this anytime soon, but maybe @ifellinaholeonce can help in the meantime

Am I right to understand rails_param 0.11.x works in both Rails 6/7, while rails_param 1.x fails for both?

hi @iMacTia

you are right here!

Thanks for bringing this up! I'll be able to take a look at this but likely not until next week.

To confirm, the behaviour from 0.11.x was that a param defined as a String (ie. foo.param! :email, String) can be given an array and each item in the array will get that validation?

hi @ifellinaholeonce,

I dont have access to the codebase right now, but as fair as i remember, the array shouldnt be valid, regardless of what is inside. email should be a string and not an array. So the exception should be raised, and not automatically have a string being coerced to array. I don't think the validation was happening for each element of the array. If was the case, it would still be an undocumented and maybe dangerous, feature.