2012-04-04 111 views
2

Rails初学者在这里..如何防止DELETE HTTP请求在这种情况下成功?

我有一个用户资源,我实现了一个应该阻止管理员用户删除自己的回调。

before_filter :admin_no_delete, only: :destroy 

def admin_no_delete 
    admin_id = current_user.id if current_user.admin? 
    redirect_to root_path if params[:id] == admin_id 
end  

如果这看起来很熟悉了一些,从迈克尔·哈特尔的轨道教程,exercise #10 here的,但我试图以不同的方式去做,而不是他建议。

我的(跛脚)测试失败

describe "deleting herself should not be permitted" do 
     before do 
     delete user_path(admin) 
     end 
     it { should_not redirect_to(users_path) } 
    end 

但暴露出删除链接管理员用户只是为了测试,并点击该链接,好像回调在执行实际成功(重定向到root_path )。

我能够使用jQuery删除记录调用销毁行动由回调(使用Web Inspector的JavaScript控制台)的保护:

$.ajax({url: 'http://localhost:3000/users/104', type: 'DELETE', success: function(result){alert(result)} }) 

如何防止一个DELETE HTTP请求寻找思路在这种情况下成功......还有关于如何正确测试这种情况的想法?

谢谢。

+0

测试是否测试什么?你不成功删除后重定向吗? – 2012-04-04 11:33:09

+0

实际上是否从数据库中删除了具有'id' 104的'User'? – 2012-04-04 11:33:12

+0

@FrederickCheung - 谢谢,我意识到我的错误在那里...删除重定向到users_path,所以应该是一个should_not ..在这种情况下,测试实际上失败 – rme 2012-04-04 12:15:19

回答

0

简单:params[:id]是一个字符串,而admin_id是一个Fixnum。你可以改变它如下,它应该工作:

redirect_to root_path if params[:id].to_i == admin_id 

虽然你使用的逻辑似乎有点奇怪。为什么要使用之前的过滤器,如果它只是一个动作,为什么要改变重定向?我认为逻辑应该是直接在摧毁行动,看起来像这样:

def destroy 
    unless current_user.admin? && current_user.id == params[:id].to_i 
    User.find(params[:id]).destroy 
    flash[:success] = "User destroyed." 
    end 
    redirect_to users_path 
end 
+0

非常感谢。该教程实际上是建议将其放入摧毁行动本身。我太想知道了 - 显然这个错误表明了这一点。我不认为我写的测试是一个很好的测试。将不胜感激任何提示,以改善它。 – rme 2012-04-04 13:37:42

+1

对于销毁操作,我认为最好的方法是检查数据库更改(或缺少,在你的情况)。我有时会做这样的事情:'lambda {删除user_path(admin)}。应该改变{User.count} .by(0)' – tsherif 2012-04-04 14:26:48

+0

我想检查count,但不知道如何在这种情况下实现它。非常感谢你的帮助! – rme 2012-04-05 01:24:15

0

你在比较admin_id,一个整数与params[:id]params中的值始终是字符串(或包含更多字符串的数组/散列),因此比较将始终失败。

+0

谢谢,是的,那是错误... – rme 2012-04-04 13:38:39

相关问题