Rails: ParamsWrapper

Recently I stumbled onto the ParamsWrapper system inside of Rails. It’s a convenient system that allows form data to be submitted without specifying the root object. For example, if you are creating a new post you can specify the name using either name=”name” or name=”post[name]”. Either way you can access the attribute using params[:post][:name].

Most of the time the system works perfectly without modification. It uses the model represented by the controller’s attr_accessor definition to determine which attributes work. However if you are not using the rails preferred naming scheme this system may no longer work as expected.

For example, let’s create a User model and a RegistrationController

[code language=”ruby”]
class User < ActiveRecord::Base
attr_accessor :name, :email
end

class RegistrationController < ApplicationController
def create
User.create params[:user]
end
end
[/code]

And a form to create the user

[code lang=”html”]
<%= form_for @user do %>
<input name="name" type="text" />
<input name="email" type="email" />
<% end %>
[/code]

Now since we can usually rely on ParamsWrapper the above code would work. However since we’ve named our controller registrations we can no longer guarantee the users parameters will exist in params[:user]. We can however fix this by calling the wrap_parameters method on the controller.

[code language=”ruby”]
class RegistrationController < ApplicationController
wrap_parameters User

def create
User.create params[:user]
end
end
[/code]

Take notice we specify the model using the class and not a symbol. By using the class the models class will be used to determine what attributes to place in the params[:user] hash. If a symbol is specified all attributes passed in will be placed into the hash.

Leave a comment

Your email address will not be published. Required fields are marked *