ばかげた質問時間:次のリクエスト仕様では、データベース内の最初のユーザーが(最初のユーザー以外の人によって)編集できないようにしています。
# 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
2つのテストは同じことをしているように見えますが、1つは失敗し、もう1つは合格します。私の理解はここでは最悪だと思います。失敗したテストで呼び出されたように、update_attributesが必要な場合は、フィルターの前にコントローラーを呼び出します。
# 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
update_attributesは私のbefore_filterを無視しますか?なぜ入れないの?