2012-04-04 67 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