2017-10-15 5 views
3

親クラスのサブクラスのプライベートメソッドを、特にRailsのApplicationController、Controllers、およびlibモジュールに関係する親クラスに含まれるモジュールから呼び出すことはできますか?親クラスのサブクラスのプライベートメソッドを、レールの親クラスに含まれるモジュールから呼び出すことはできますか?

コントローラー名を変更する必要がある場合は、モデル名を反映するメソッド名を変更することを検討してください。

私はこれは本当に悪いコーディングで感じ、Railsアプリケーションからこの

例についてどう思うかコミュニティを知りたいと思った:

/lib/some_module.rb

module SomeModule 
    include SomeModuleResource 

    def filtering_method 
    calling_method 
    end 

    def calling_method 
    fetch_object 
    end 
end 

/libに/ some_module_resource.rb

module SomeModuleResource 
    def fetch_object 
    note 
    end 
end 

/app/controllers/application_controlle r.rb

class ApplicationController < ActionController::Base 
    include SomeModule 

    before_action :filtering_method 

end 

/app/controllers/notes_controller.rb

class NotesController < ApplicationController 

    def show 
    end 

    private 

    def note 
    @note ||= Note.find(param[:id])) 
    end 
end 
+0

私はあなたが達成しようとしているのだろうか? 'show'メソッドで' note'を呼び出したり、コントローラーで 'before_action:note'を定義したりしないでください。もっと読みやすく、理解しやすいIMHO。 – spickermann

+0

私はこのコードを私が作業しているアプリケーションで見たので、これはコーディングの方法が間違っていると他人に正当化する必要があるため、これを尋ねています。 – Satya

+2

他の開発者になぜそうしたのか尋ねましたか? 1行のコードを2つのモジュールと間接指定のいくつかのステップに置き換えることをお勧めします。私はこの例が一目見てばかげて複雑に見えることに同意しますが、この複雑さを導入する決定には理由や歴史があるに違いありません。 – spickermann

答えて

1

私は、これは、あなたが特定のインターフェイスを期待していたが(メソッド、変数悪い必要はないという意見だけど、私は次のように追加しますモジュールを含んでいるクラスからなど):#noteは、あなたはそれが必要かワットた忘れていたので、(それを実装せずに呼び出された

module SomeModuleResource 
    def fetch_object 
    note 
    end 

    private 

    def note 
    raise NotImplementedError 
    end 
end 

この方法では、 hatever)a NotImplementedErrorが呼び出されます。

もう1つの選択肢は、それを回避してより一般的な解決策を作成することです。

module SomeModuleResource 
    def fetch_object 
    note 
    end 

    private 

    def note 
    klass = params[:controller].classify.constantize 
    instance = klass.find(params[:id]) 

    var_name = "@#{klass.underscore}" 
    instance_variable_set(var_name, instance) unless instance_variable_get(var_name) 
    end 
end 

また、あなたは独自の実装を渡すことができるようbefore_actionようなクラスのヘルパーメソッドを作成することができます。すべてのコントローラが同じように振る舞う場合たとえば、あなたは次の操作を行うことができ、上記の。

module SomeModule 
    include SomeModuleResource 

    def self.included(base) 
    base.extend(ClassMethods) 
    end 

    def filtering_method 
    calling_method 
    end 

    def calling_method 
    fetch_object 
    end 

    module ClassMethods 
    def custom_before_action(&block) 
     define_method(:note, &block) 
     private :note 

     before_action :filtering_method 
    end 
    end 
end 

custom_before_filter { @note ||= Note.find(params[:id]) }は、すべてのコントローラで(後で)使用できます。

上記はあなたにアイデアを提示するためのものです。私はあなたが問題のより良い解決策を見つけることができると確信していますが、これはうまくいけば正しい方向にあなたを指しています。

参照:Alternatives to abstract classes in Ruby?あるいは、Rubyで抽象クラスを検索すると、このテーマについて詳しく知ることができます。

+0

私は最初のコードサンプルに同意します。サブクラスのメソッドが実装されることが期待される場合、実装されていることを確認する必要があります。それが強制されなければ、後で変更するとコードが破損します。 – Satya

関連する問題