With the flurry of new features introduced in Rails 4 I was interested in how they would affect every day developer life here at Pivotal Labs. Luckily one of my fellow Pivots Robbie Clutton had decided to dive in and investigate testing strong paramters.
On my previous project we had already adopted strong parameters on a Rails 3.2 codebase and hadn’t come up with a pattern we particularly liked. Seeing real promise in the technique Robbie suggested I decided to give it a go. Unfortunately we ran into a snag when using update_attributes
when overriding the ActionController::Parameters
constructor as suggested.
It turns out that under the hood update_attributes
dups the object, creating a new instance with the filtered params. If you happened to slice your params in the constructor using require
you will no longer have the top level key user
. This results in a ActionController::ParameterMissing: param not found: user
exception.
So in the spirit of standing on the shoulders of those that came before, I give you the modifications we came up with.
class UsersController < ApplicationController
def update
user = User.find(params[:id])
user.update_attributes(UserParams.permit(params))
respond_with user
end
class UserParams
def self.permit params
params.
require(:user).
permit(:first_name, :last_name)
end
end
end
And the updated spec
describe UsersController::UserParams do
describe ".permit" do
it "returns the cleaned params" do
user_params = { first_name: "Kanye", last_name: "West" }
params = ActionController::Parameters.new(user: { foo: "foo" }.merge(user_params))
permitted_params = UsersController::UserParams.permit(params)
expect(permitted_params).to eq(user_params.with_indifferent_access)
end
end
end