2017-09-27 15 views
2

私はRailsとバックエンドAPIの開発にはかなり新しいので、私が概念を誤用すると私は言い訳になります。今私は、コードベースの周りに振り回され、APIコントローラに混在している救済された例外の明示的なリストをモジュールとして組み込むことに向けて、多量の条件付きエラー処理コードをリファクタリングしようとしています。これにより、アクティブなレコードメソッドにバンオプションを使用し、エラー処理コードを1つの場所に置くことができる限り、捕捉された各例外にカスタムの、ただし任意のコードを付加できます。これまでのところ、エラー処理モジュールのために、私はこのようなものを持っている:layouts/api/errorsはJBuilderのを使用して構築された図であるRailsでモジュールを使ってエラーを処理する最も良い方法は?

# app/lib/error/error_handling.rb 
module Error 
    module ErrorHandling 
    def self.included(klass) 
     klass.class_eval do 
     rescue_from ActiveRecord::RecordNotFound do |e| 
      respond(:record_not_found, 404, e.to_s) 
     end 
     rescue_from ActiveRecord::ActiveRecordError do |e| 
      respond(e.error, 422, e.to_s) 
     end 
     rescue_from ActiveController::ParameterMissing do |e| 
      response(:unprocessable_entitry, 422, e.to_s) 
     end 
     rescue_from ActiveModel::ValidationError do |e| 
      response(e.error, 422, e.to_s) 
     end 
     rescue_from CustomApiError do |e| 
      respond(e.error, e.status, e.message.to_s) 
     end 
     rescue_from CanCan::AccessDenied do 
      respond(:forbidden, 401, "current user isn't authorized for that") 
     end 
     rescue_from StandardError do |e| 
      respond(:standard_error, 500, e.to_s) 
     end 
     end 
    end 

    private 

    def respond(_error, _status, _message) 
     render "layouts/api/errors", status: _status 
    end 
    end 
end 

。我々が持っているApiControllerで :

# app/controllers/api/api_controller.rb 
module Api 
    class ApiController < ApplicationController 
    include Error::ErrorHandling 

    attr_reader :active_user 

    layout "api/application" 

    before_action :authenticate_by_token! 
    before_action :set_uuid_header 

    respond_to :json 
    protect_from_forgery with: :null_session 
    skip_before_action :verify_authenticity_token, if: :json_request? 

    private 

    ... 

end 

残念ながら、これは動作するようには思えません。テストを実行すると、プライベートメソッドはまったく読み込まれておらず、未定義とみなされます。ここでは、より具体的には

は、放出されたエラーです:

uninitialized constant Error::ErrorHandling::ActiveController 

active_userset_active_userという名前のメソッドによって、インスタンス変数の内部で設定されている属性である
undefined local variable or method `active_user' for Api::FooController 

。明らかに呼び出されていないのは明らかです。

しかし、ErrorHandlingモジュールが評価されています。これはどうやってできるの?名前空間が間違っているのですか?

読んでいただきありがとうございます。

+0

どのプライベートメソッドが未定義であるかを詳しく教えてください。コントローラのオンまたはモジュールのオン?可能であれば、スタックトレースも役に立ちます。 – ulferts

+0

投稿を更新しました。前述したように、モジュールは評価されていますが、実際に定義されていると、モジュール内の 'unitialized constant'エラーと、' undefined local variableまたは 'メソッドがAPIコントローラの内部にあります。おそらくモジュールのエラーは、 'include'以下のコードが評価されないようにしますか? – dynsne

+0

私は「未定義メソッド」の問題に関する基本的なポインタしか提供できませんでした。エラーを発生させるコードを表示すると、より具体的なヘルプを提供することができます。 – ulferts

答えて

1

答えは2つの部分に分かれていますが、私は2つの別々の問題があると信じています。

unitinalized定数エラー

uninitialized constant Error::ErrorHandling::ActiveController 

このこの

rescue_from ActiveController::ParameterMissing do |e| 
    response(:unprocessable_entitry, 422, e.to_s) 
end 

変化させることによって固定することができるエラー:

rescue_from ::ActiveController::ParameterMissing do |e| 
    response(:unprocessable_entitry, 422, e.to_s) 
end 
を10

ActiveControllerの前に::を追加)

ルビの定数ルックアップでは、字句のネストが考慮されます。あなたは

module Error 
    module ErrorHandling 
    ... 
    end 
end 

内で一定の基準として、ルビーは、一定の前に定義されていない場合は、この名前空間内の定数を見つけようとします。前もって::を指定すると、ルックアップは定数検索のネストを無視します。いくつかのコードは、それが定義されていないクラスApi::FooControllerインスタンス方法active_userを呼び出しているので

未定義のローカル方法

エラー

undefined local variable or method `active_user' for Api::FooController 

が上昇します。

+0

ありがとう、進歩を遂げた。私は今ルビーについてもっと理解しています! – dynsne

+0

助けになるのはうれしいです。定数ルックアップの詳細については、[このページで](https://cirw.in/blog/constant-lookup.html)をご覧ください。 – ulferts

関連する問題