Domanda

The example used in the documentation (http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters) for strong parameters is:

params.require(:person).permit(:name, :age)

However, this doesn't work because require() returns the value of the parameter, not another parameter object that permit() can be called on.

$ rails console
1.9.3p286 :005 > params = ActionController::Parameters.new(person: 1, name: "Joe", age: 30)
 => {"person"=>1, "name"=>"Joe", "age"=>30} 
1.9.3p286 :006 > params.require(:person).permit(:name, :age)
NoMethodError: undefined method `permit' for 1:Fixnum
    from (irb):6
    from /Users/jeremyburton/.rvm/gems/ruby-1.9.3-p286/gems/railties-4.0.0/lib/rails/commands/console.rb:90:in `start'
    from /Users/jeremyburton/.rvm/gems/ruby-1.9.3-p286/gems/railties-4.0.0/lib/rails/commands/console.rb:9:in `start'
    from /Users/jeremyburton/.rvm/gems/ruby-1.9.3-p286/gems/railties-4.0.0/lib/rails/commands.rb:64:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'

Additionally, it seems odd that require can only take 1 parameter. It seems that you should be able to do:

params.require(:a, :b).permit(:c, :d)

Whereas, what you have to do is:

params.require(:a)
params.require(:b)
params.permit(:a, :b, :c, :d)

which doesn't seem very DRY - if a parameter is required then it is by definition permitted, surely.

Am I missing something?

È stato utile?

Soluzione

The intention of require is for working with Rails form_for objects, whereby the params hash will include the name of the object you're wrapping a form around. So like this:

ActionController::Parameters.new(person: { name: 'Francesco' }).require(:person)

In this case, the form_for would have been wrapped around a Person object. So the .require(:person) will then wrap the resulting hash ({ name: 'Francesco' }) up into an ActionController::Parameters object which can respond to .permit. So your test just wasn't mimicking the expected params use-case.

Also, it makes sense that require would only accept one argument since you'd want to setup a unique <attribute>_params method per object type since, again, these are meant to be wrappers around a specific object. But, normally you'd only have 1 root object being sent into a form submit, and sub objects within that.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top