2012-03-29 51 views
0

我在控制器中有許多現有的方法。每種方法都需要驗證。Ruby方法中的兩個呈現語句和對JQuery AJAX調用的響應

爲此,我在應用程序控制器中創建了一個驗證方法。

我想從每個單獨方法的開始調用此驗證方法,這將在繼續之前檢查用戶是否具有所需的組。驗證方法返回true或false。 如果驗證方法返回false,則瀏覽器將重定向到「驗證失敗」頁面,並且該方法的其餘部分不會執行。 使用JQuery調用原始方法。

我將展示一些代碼,然後解釋的問題是什麼:

jQuery的Ajax請求:(通用代碼,但只是爲了說明)

jQuery.ajax({ 
    url:"examplecontroller/examplemethod/" + ID, 
    success: function(data,textstatus,XMLHttpRequest) 
    { 
    } 
}) 

方法JQuery的請求呼叫:

def examplemethod 
    id = ExampleDatabase.find(params[:id]) 

    #redirect to validationFail page if validation check returns false# 
    render "/validationFail" if !(check_groups(id, "type")) 

    ...other code etc... 

    render :text => done 

end 

驗證結束的方法:

def check_groups(id, type) 

    ... other code etc .... 

    if userGroups.include? requiredGroup then 
     return true 
    else 
     return false 
    end 
end 

關於這行調用驗證方法 -

render "/validationFail" if !(check_groups(id, "type")) 

我做了這樣的,因爲我只想要一個簡短,簡潔,一行代碼,我只是堅持在位每個方法的開始或者驗證,並允許執行其餘的方法。或者它不驗證,它會停止執行其餘的方法。

我的問題是,有第二個'渲染'線似乎無效的第一個。 如果我有第二個「渲染」線,第一個不會重定向到「驗證失敗」頁面。 如果我將第二條驗證線取出,那麼對JQuery Ajax調用沒有響應(假定該方法驗證並完全執行)。這導致了Firebug中的錯誤,顯然我的AJAX'成功'代碼沒有執行。

我知道我可以使用IF語句來呈現一個或另一個,即:

def examplemethod 
    id = ExampleDatabase.find(params[:id]) 

    if !(check_groups(id, "type")) then 
     render "/validationFail" 
    else 

     ...other code etc... 

     render :text => done 

    end 
end 

但是我真的不想去通過和重組一樣,每一個方法,我寧願只使用每個方法開始處的一條簡單線條,它返回true並繼續,或者返回false並且不會繼續。

很奇怪(對我有限的知識)第二個渲染會影響第一個渲染,因爲我認爲使用渲染會阻止後續代碼執行......我研究過使用redirect_to代替第一個渲染,但是我不能不要讓這個工作。

任何人都可以提出一個更好的方式來做到這一點?

回答

1

我認爲你在這裏找的是before_filterbefore_filters允許您在選定操作之前執行代碼並呈現內容,如果過濾器返回false則取消操作。對於過濾器can be found here的文檔,而是換了一塊示例代碼,你很可能在尋找這樣的事情:

def TestController < ApplicationController 
    before_filter :check_groups 

    def examplemethod 
    id = ExampleDatabase.find(params[:id]) 

    render :text => 'done' 
    end 

    private 

    def check_groups 
    if !(check_groups(id, "type")) 
     render '/validationFail' 
     return false 
    end 
    end 
end 

before_filter返回false將停止動作的執行,防止其他過濾器(或動作本身)從被調用。如果你在整個地方都使用這種方法,你甚至可以把它放在你的應用程序控制器中,並且你可以通過在the documentation中讀取更多的方法來節制執行哪些方法before_filter

+0

謝謝,這解決了我的問題。 Before_filter完美地工作。 – Exbi 2012-03-30 18:19:22