2012-03-29 42 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