Ruby on Rails教程第10章练习RSpec失败

我正在研究Rails教程第10章中的练习,并通过练习让我确保管理员用户无法自行删除。 我最初的想法是简单地检查当前用户的id并将其与params [:id]进行比较,以确保它们不相等。 我在Users控制器中的销毁操作如下所示:

def destroy if current_user.id == params[:id].to_i flash[:notice] = "You cannot delete yourself." else User.find(params[:id]).destroy flash[:success] = "User destroyed." end redirect_to users_path end 

当我在应用程序中手动测试它时,这非常有效,但是我的RSpec测试中有3个失败并出现相同的“未定义方法’to_i’”错误(如下所示):

 1) UsersController DELETE 'destroy' as an admin user should destory the user Failure/Error: delete :destroy, :id => @user NoMethodError: undefined method `to_i' for # # ./app/controllers/users_controller.rb:48:in `destroy' # ./spec/controllers/users_controller_spec.rb:310:in `block (5 levels) in ' # ./spec/controllers/users_controller_spec.rb:309:in `block (4 levels) in ' 2) UsersController DELETE 'destroy' as an admin user should redirect to the users page Failure/Error: delete :destroy, :id => @user NoMethodError: undefined method `to_i' for # # ./app/controllers/users_controller.rb:48:in `destroy' # ./spec/controllers/users_controller_spec.rb:315:in `block (4 levels) in ' 3) UsersController DELETE 'destroy' as an admin user should not allow you to destroy self Failure/Error: delete :destroy, :id => @admin NoMethodError: undefined method `to_i' for # # ./app/controllers/users_controller.rb:48:in `destroy' # ./spec/controllers/users_controller_spec.rb:321:in `block (5 levels) in ' # ./spec/controllers/users_controller_spec.rb:320:in `block (4 levels) in ' 

如果我使用params [:id]来查找用户并将其与current_user进行比较,就像我在下面那样,那么它在app和RSpec中都有效。

 def destroy if current_user == User.find(params[:id]) flash[:notice] = "You cannot delete yourself." else User.find(params[:id]).destroy flash[:success] = "User destroyed." end redirect_to users_path end 

为什么使用“to_i”方法在RSpec中出现问题? 如果有人想知道我倾向于这种方法,因为我认为最好简单地将当前用户ID与目标删除用户的id(通过params [:id])进行比较,而不是将数据库命中为“find”用户。

作为参考,这是我的RSpec测试:

  describe "DELETE 'destroy'" do before(:each) do @user = Factory(:user) end ... describe "as an admin user" do before(:each) do @admin = Factory(:user, :email => "admin@example.com", :admin => true) test_sign_in(@admin) end it "should destory the user" do lambda do delete :destroy, :id => @user end.should change(User, :count).by(-1) end it "should redirect to the users page" do delete :destroy, :id => @user response.should redirect_to(users_path) end it "should not allow you to destroy self" do lambda do delete :destroy, :id => @admin end.should change(User, :count).by(0) response.should redirect_to(users_path) flash[:notice].should =~ /cannot delete yourself/ end end end 

任何帮助,将不胜感激!

在你的规范中,尝试在你的:id参数上使用@user.id而不是@user (我意识到Tutorial说只是使用@user ,但是可能正在进行没有正确提取id的地方):

 delete :destroy, :id => @user.id 

但你可以考虑重组到这样的事情:

 @user = User.find(params[:id]) if current_user == @user flash[:notice] = "You cannot delete yourself." else @user.destroy flash[:success] = "User destroyed." end