2012-07-14 224 views
2

为什么我不能用以下方法拯救任何东西?为什么ActiveRecord :: StatementInvalid无法在此Rails方法中获救?

def get_things 
    begin 
    things= @member.things.where("id>?",params[:id]) 
    rescue ActiveRecord::StatementInvalid 
    render(inline: "RESCUED ActiveRecord::StatementInvalid") 
    return 
    rescue 
    render(inline: "RESCUED something") 
    return 
    end 
    render(inline: "#{things.first.title}") 
end 

时凭有效身份证叫,它的工作原理:

$ curl -vd "id=3" http://localhost:3000/get_things 

,但如果我传递一个错误的,如:

$ curl -vd "id=3,0" http://localhost:3000/get_things 
$ curl -vd "id='3'" http://localhost:3000/get_things 

异常没有被救出:

< HTTP/1.1 500 Internal Server Error 
<h1> 
    ActiveRecord::StatementInvalid 
    in ApplicationController#get_things 
</h1> 
<pre>PG::Error: ERROR: invalid input syntax for integer: &quot;'3'&quot; 

只有当渲染发生在里面开始/救援块

def get_things 
    begin 
    things= @member.things.where("id>?",params[:id]) 
    render(inline: "#{things.first.title}") 
    rescue ActiveRecord::StatementInvalid 
    render(inline: "RESCUED ActiveRecord::StatementInvalid") 
    return 
    end 
end 

它按预期工作:

$ curl -vd "id='3'" http://localhost:3000/get_things 
    < HTTP/1.1 200 OK 
    RESCUED ActiveRecord::StatementInvalid 

回答

7

据我所知,您的案例中的things将是一个包含您的查询信息的类,但只有当您尝试访问基于查询的元素(如things.first)时才会执行该查询。

things= @member.things.where("id>?",params[:id]) # query not run 
things= things.order("id desc") # still not run 
things.first.title # now the query runs, the statement can be invalid 

这就是为什么它不能被救出,因为在你的渲染线,在发生异常时,而不是在创建things的。

这应该没问题:

def get_things 
    begin 
    things= @member.things.where("id>?",params[:id]) 
    thing_title = things.first.title 
    rescue ActiveRecord::StatementInvalid 
    render(inline: "RESCUED ActiveRecord::StatementInvalid") 
    return 
    rescue 
    render(inline: "RESCUED something") 
    return 
    end 
    render(inline: "#{thing_title}") 
end 
+0

谢谢你,这是相当有趣的。 – 2012-07-14 21:40:00

-1

你可以改变一个参数为int:

params[:id] = params[:id].to_i if params[:id].present? 
things= @member.things.where("id>?",params[:id]) 

或者你可以在config/routes.rb为PARAMS添加验证:

resources :things, :constraints => {:id => /\d+/} 
相关问题