Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails RubyonRails教程第10章练习RSpec失败_Ruby On Rails_Ruby On Rails 3_Rspec Rails - Fatal编程技术网

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

Ruby on rails RubyonRails教程第10章练习RSpec失败,ruby-on-rails,ruby-on-rails-3,rspec-rails,Ruby On Rails,Ruby On Rails 3,Rspec Rails,我正在做Rails教程第10章中的练习,但遇到了一个问题,这让我确保管理员用户不能删除自己。我最初的想法是简单地检查当前用户的id,并将其与params[:id]进行比较,以确保它们不相等。我的用户控制器中的销毁操作如下所示: def destroy if current_user.id == params[:id].to_i flash[:notice] = "You cannot delete yourself." else User.find(params[:id]

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

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
@user = User.find(params[:id])
if current_user == @user
  flash[:notice] = "You cannot delete yourself."
else
  @user.destroy
  flash[:success] = "User destroyed."
end
当我在应用程序中手动测试它时,这非常有效,但我的3个RSpec测试失败,出现了相同的“undefined method”to_I'”错误(如下所示):

为什么RSpec中使用“to_i”方法会出现问题?如果有人想知道我是否倾向于这种方法,因为我认为最好是将当前用户id与要删除的用户id进行比较(通过params[:id]),而不是点击数据库“查找”用户

作为参考,这是我的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
(我知道教程中说只使用
@user
,但在未正确提取id的情况下可能会出现问题):

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

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
@user = User.find(params[:id])
if current_user == @user
  flash[:notice] = "You cannot delete yourself."
else
  @user.destroy
  flash[:success] = "User destroyed."
end

在您的规范中,尝试在
:id
参数上使用
@user.id
而不是
@user
(我知道教程中说只使用
@user
,但可能在未正确提取id的情况下发生了一些事情):

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

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
@user = User.find(params[:id])
if current_user == @user
  flash[:notice] = "You cannot delete yourself."
else
  @user.destroy
  flash[:success] = "User destroyed."
end

所以传递@user.id(或者@admin.id,在引用的地方)是有效的!所以我猜RSpec没有正确提取id。很有趣。谢谢你的帮助@Dylan,比较用户对象和用户ID更安全吗?在这种情况下,您通常需要在.destroy中使用该对象,因此执行User.find似乎不是一种“浪费”。只是想知道是否有一个关于是否应该在对象或ID级别进行身份比较的一般规则。@至少在这种情况下,标记,我倾向于在delete调用中使用
id
,因为这是在实际的HTTP请求中传递它的方式。就比较
current\u user==@user
而言,如果current\u user.id==params[:id],那么实际上要做的工作量可能会少一些,因为如果该值为true,那么实际上根本不需要
@user
对象。因此传递@user.id(或@admin.id,在引用的地方)是有效的!所以我猜RSpec没有正确提取id。很有趣。谢谢你的帮助@Dylan,比较用户对象和用户ID更安全吗?在这种情况下,您通常需要在.destroy中使用该对象,因此执行User.find似乎不是一种“浪费”。只是想知道是否有一个关于是否应该在对象或ID级别进行身份比较的一般规则。@至少在这种情况下,标记,我倾向于在delete调用中使用
id
,因为这是在实际的HTTP请求中传递它的方式。至于比较
current\u user==@user
,如果current\u user.id==params[:id],那么实际上要做
的工作量可能会更小,因为如果这一计算结果为真,那么就永远不需要
@user
对象。问得好,谢谢分享测试代码。我发现flash测试没有任何作用——你需要添加
。should
flash[:注意]。should=~/不能删除你自己/
刚刚看到这个评论。谢谢。好问题,谢谢分享测试代码。我发现flash测试没有任何作用——你需要添加
。should
flash[:注意]。should=~/不能删除你自己/
刚刚看到这个评论。谢谢