Skip to content

Instantly share code, notes, and snippets.

@israelb
Forked from jeremyw/accounts_controller.rb
Created March 9, 2017 17:31
Show Gist options
  • Save israelb/e8f774b55a500ab0f02aba39eb32df6e to your computer and use it in GitHub Desktop.
Save israelb/e8f774b55a500ab0f02aba39eb32df6e to your computer and use it in GitHub Desktop.
Testing Rails 4 strong parameters
class AccountsController < ApplicationController
def update
@account = Account.find(params[:id])
respond_to do |format|
if @account.update_attributes(account_params)
format.html { redirect_to @account, notice: 'Account was successfully updated.' }
else
format.html { render action: "edit" }
end
end
end
private
def account_params
# note that the Account#name attribute is permitted, but Account#balance is not
params.require(:account).permit(:name)
end
end
require 'spec_helper'
describe AccountsController do
describe "PUT update" do
describe "with forbidden params" do
let(:account) { Account.create! balance: 100.0, name: 'Checking' }
it "does not update the forbidden params" do
put :update,
id: account.to_param,
account: { 'name' => 'Savings', 'balance' => '1000000' }
assigns(:account).name.should eq('Savings') # explicitly permitted
assigns(:account).balance.should eq(100.0) # implicitly forbidden
response.should redirect_to account
end
end
end
end

This is a simple example of strong parameters in Rails (Rails 4 or Rails 3.2 with the strong_parameters gem). The test demonstrates that the Account's name attribute can be updated via the update action, but its balance cannot. The system works.

However, how far should we take these kinds of tests? Now that we've moved this responsibility from the model to the controller, should we invest in controller specs/tests to:

  1. ensure that all permitted attributes can be updated?
  2. ensure that any forbidden attributes cannot be updated?

Is there a good, clean, expressive way to test the private account_params method in the controller, to verify the contents of the whitelist rather than the effects of the whitelist? I've used shoulda-style "should(_not) allow_mass_assignment_of" macros in the past. There doesn't appear to be anything analogous for strong_parameters yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment