2012-07-14 217 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+/} 
相關問題