首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ruby on Rails教程第10章练习RSpec故障

Ruby on Rails教程第10章练习RSpec故障
EN

Stack Overflow用户
提问于 2011-06-30 03:33:22
回答 1查看 1.9K关注 0票数 1

我正在做Rails教程第10章中的练习,但我在练习中遇到了一个问题,那就是我要确保管理员用户不能删除自己。我最初的想法是简单地检查当前用户的id,并将其与params:id进行比较,以确保它们不相等。我在用户控制器中的销毁操作如下所示:

代码语言:javascript
复制
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测试都失败了,出现了同样的“未定义的方法'to_i'”错误(如下所示):

代码语言:javascript
复制
1) UsersController DELETE 'destroy' as an admin user should destory the user
   Failure/Error: delete :destroy, :id => @user
     NoMethodError:
       undefined method `to_i' for #<User:0x000001032de188>
   # ./app/controllers/users_controller.rb:48:in `destroy'
   # ./spec/controllers/users_controller_spec.rb:310:in `block (5 levels) in <top (required)>'
   # ./spec/controllers/users_controller_spec.rb:309:in `block (4 levels) in <top (required)>'

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 #<User:0x000001032b5850>
   # ./app/controllers/users_controller.rb:48:in `destroy'
   # ./spec/controllers/users_controller_spec.rb:315:in `block (4 levels) in <top (required)>'

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 #<User:0x0000010327e350>
   # ./app/controllers/users_controller.rb:48:in `destroy'
   # ./spec/controllers/users_controller_spec.rb:321:in `block (5 levels) in <top (required)>'
   # ./spec/controllers/users_controller_spec.rb:320:in `block (4 levels) in <top (required)>'

如果我使用params:id来查找用户,并将其与下面的current_user进行比较,那么它在应用程序和RSpec中都可以工作。

代码语言:javascript
复制
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

为什么RSpec中的"to_i“方法会有问题?如果有人想知道我倾向于这种方法,因为我认为最好简单地将当前用户id与要删除的用户的id进行比较(通过params:id),而不是点击db来“找到”该用户。

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

代码语言:javascript
复制
  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

任何帮助都将不胜感激!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-06-30 03:57:37

在你的规范中,尝试在你的:id参数上使用@user.id而不是@user (我知道教程说只使用@user,但可能有一些id没有被正确提取的地方):

代码语言:javascript
复制
delete :destroy, :id => @user.id

但您可以考虑将结构调整为如下所示:

代码语言:javascript
复制
@user = User.find(params[:id])
if current_user == @user
  flash[:notice] = "You cannot delete yourself."
else
  @user.destroy
  flash[:success] = "User destroyed."
end
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6526189

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档