Question

Dumb question time: In the following request spec, I try to make sure that the first user in my db can't be edited (by anyone besides the first user).

# user is not logged in during these tests

# variant 1 - this passes
describe "first user" do
  let(:first_user){ FactoryGirl.create(:admin) }

  # use put to modify the user
  before { put user_path(first_user, email: 'tst@test.com') }

  # this passes, the response is a redirect
  specify { response.should redirect_to(root_path) }
end

# variant 2 - this test fails
describe "first user" do
  let(:first_user){ FactoryGirl.create(:admin) }

  # this fails, email is updated
  it "can't be updated or edited" do
    expect do
      first_user.update_attributes(email: 'email@test.com')
    end.not_to change(first_user.reload, :email)
  end
end

The two tests appear to do the same thing, but one fails and one passes. I guess my understanding sucks here. Should update_attributes, as called in the failing test, invoke my controller's before filter:

# users_controller.rb
before_filter correct_user, only: [:edit, :update]

private

# pretty messy, but ensures that ordinary users can only
# edit their own accounts, that admin users can
# edit all accounts, except for the first one. 
# I believe it also ensures that the first_user 
# can only be edited by the owner of the first account, i.e. me
# due to the fact that the first condition of the `unless` clause will pass
# if the current_user is the first_user. The complexity is necessary to prevent
# other admins, from being able to edit the first_user.
def correct_user
  @user=User.find(params[:id])
  redirect_to(root_path, only_path: true) unless current_user?(@user) || ( current_user.admin? && !first_user?(@user) )
end

def first_user?(user)
  user==User.first
end

Does update_attributes ignore my before_filter? Why doesn't put?

Was it helpful?

Solution

update_attributes isn't a request, it's a model method--filters are meaningless outside a request context.

"put" is a request, so filters are run.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top