Rails duplicated the parameters inside the resource

All we need is an easy explanation of the problem, so here it is.

I am using the Angular Resource and I don’t understand why Rails duplicated the parameters and put it inside the resource name. I just need to understand why this is happening.

// post data

// rails parameters 
Parameters: {"title"=>"asdsad", "presentation"=>{"title"=>"asdsad"}}

Duplicate because welcome to Stackoverflow where you need 50 points to comments so this happen. I really so sorry: AngularJS $resource sending out an extra "registration" hash?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

..if you’ve turned on config.wrap_parameters in your initializer [check the file
config/initializers/wrap_parameters.rb] or [you] are calling
wrap_parameters() in your controller…the parameters will be cloned and
wrapped in the key according to your controller’s name by default.


In other words, what you are seeing is the default way rails enters things in the params hash.

Method 2

I had the same question but I hadn’t understood the problem and needed a different solution.

In my passwords controller (for enabling password reset via email), my parameters looked like this:

{"email"=>"[email protected]", "code"=>"123", "password"=>"[FILTERED]", "password"=>{"email"=>"[email protected]", "code"=>"123", "password"=>"[FILTERED]"}}

I thought, “why are my params duplicated inside of password“, not realizing that the outer password was coming from the resource name. (Thanks, 7stud!) But if I added wrap_parameters false at the top of my controller to flatten out the params, then I couldn’t use the ‘require/permit’ pattern for strong params:

def forgot_password_params
    params.require(:password).permit(:email, :password, :code)

To make this more legible, I used wrap_parameters to rename the outer password ref in the params. The code:

wrap_parameters "reset" 
def forgot_password_params
    params.require(:reset).permit(:email, :password, :code)

and the resulting params: {"email"=>"[email protected]", "code"=>"123", "password"=>"[FILTERED]", "reset"=>{"email"=>"[email protected]", "code"=>"123", "password"=>"[FILTERED]"}}

I then immediately ran into a related issue where for an in-app password reset, I passed in newPassword from my form but it was not in my params. By default, params only include attributes from the model. wrap_parameters let me fix this as well:

wrap_parameters :user, include: [:username, :email, :password, :newPassword]

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply