15

アプリケーションがデータベースに存在しない ID を検索する状況に遭遇しました。例外がスローされます。もちろん、これは Web 開発者にとって非常に標準的な状況です。

この回答のおかげで、次のようにレスキューを使用すると状況がかなりきれいに処理されることがわかります。

def show
  @customer = Customer.find(params[:id])
  rescue ActiveRecord::RecordNotFound #customer with that id cannot be found
    redirect_to action: :index        #redirect to index page takes place instead of crashing
end

顧客が見つからない場合、ユーザーはインデックス ページにリダイレクトされます。これは絶対にうまくいきます。

さて、これでいいのですが、show、edit、destroy などのアクション、つまり特定の ID を必要とするすべてのコントローラー メソッドで同じレスキュー試行を行う必要があります。

そうは言っても、ここに私の質問があります: 私のコントローラーに、そのメソッドのいずれかでIDが見つからない場合、インデックスページにリダイレクトする(または、一般に、特定のタスクを実行する)ことを一般的に伝える方法はありませんか? )?

4

4 に答える 4

34

rescue_fromこのタスクには使用する必要があります。アクション コントローラー概要ガイドの例を参照してください。

class ApplicationController < ActionController::Base
  rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found

  private

  def record_not_found
    redirect_to action: :index
  end
end
于 2012-11-17T20:38:48.213 に答える
8

Rails には組み込みのrescue_fromクラス メソッドがあります。

class CustomersController < ApplicationController
  rescue_from ActiveRecord::RecordNotFound, with: :index
  ...
end
于 2012-11-17T20:38:05.977 に答える
3

(すべてのコントローラーでグローバルにこれを行うのではなく) 単一のコントローラー内でこれを行うことについて話している場合は、いくつかのオプションがあります。

before_filter を使用してリソースをセットアップできます。

class CustomerController < ApplicationController
  before_filter :get_customer, :only => [ :show, :update, :delete ]

  def show
  end

  private

  def get_customer
    @customer = ActiveRecord.find(params[:id])
    rescue ActiveRecord::RecordNotFound
      redirect_to :action => :index
  end
end

または、代わりにメソッドを使用することもできます。ビュー内でインスタンス変数を使用するのではなく、この方向に進んでおり、問題の解決にも役立ちます。

class CustomerController < ApplicationController
  def show
    # Uses customer instead of @customer
  end

  private

  def customer
    @customer ||= Customer.find(params[:id])
    rescue ActiveRecord::RecordNotFound
      redirect_to :action => :index
  end
  helper_method :customer
end
于 2012-11-17T20:45:42.040 に答える
1

場合によっては、 ではなく を使用することをお勧めしModel.find_by_id(id)ますModel.find(id)。例外をスローする代わりに、 を.find_by_id返しますnil。レコードが見つからなかった場合。

避けるために、必ず nil をチェックしてくださいNoMethodError!

PS価値があるのModel.find_by_id(id)は、機能的には と同等Model.where(id: id)であり、必要に応じて追加の関係を構築できます。

于 2012-11-17T20:44:35.477 に答える