labs

Testing Strong Parameters – Redux

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