4

次の方法で何も救出できないのはなぜですか?

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

有効な ID で呼び出されると、次のように機能します。

$  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;

begin/rescue ブロック内でレンダリングが発生する場合のみ

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
4

2 に答える 2

9

私の知る限り、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
于 2012-07-14T13:35:16.753 に答える
-1

パラメータを int に変更できます。

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

または、params のバリデーターを次のように追加できますconfig/routes.rb

resources :things, :constraints => {:id => /\d+/}
于 2012-07-14T13:27:03.710 に答える