Rails初学者......
我有一个用户资源,我实现了一个回调,它应该阻止管理员用户自行删除。
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
如果这对某些人来说很熟悉,那就是来自Michael Hartl的rails教程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调用destroy动作来删除受回调保护的记录(使用Web Inspector的javascript控制台):
$.ajax({url: 'http://localhost:3000/users/104', type: 'DELETE', success: function(result){alert(result)} })
在这种情况下寻找有关如何防止DELETE HTTP请求成功的想法..还有关于如何正确测试这种情况的任何想法?
感谢。
答案 0 :(得分:0)
您正在比较admin_id
,一个带params[:id]
的整数。 params
中的值始终是字符串(或包含更多字符串的数组/哈希),因此比较将始终失败。
答案 1 :(得分:0)
简单:params[:id]
是一个字符串,而admin_id
是一个Fixnum。您可以按如下方式更改它,它应该可以工作:
redirect_to root_path if params[:id].to_i == admin_id
你使用的逻辑对我来说似乎有些奇怪。为什么使用前置过滤器,如果只是一个操作,为什么要更改重定向?我认为逻辑应该直接在destroy动作中看起来像这样:
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