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

class User < ActiveRecord::Base
  attr_accessor :name, :email
end

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

And a form to create the user

<%= form_for @user do %>
  <input name="name" type="text" />
  <input name="email" type="email" />
<% end %>

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.

class RegistrationController < ApplicationController
  wrap_parameters User

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

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 Reply