Railsではbefore_filter
、コントローラーにを追加できます。ベースコントローラーが次のようになっていると仮定します。
before_filter :my_base_filter
これを前提として、この基本コントローラーから継承するコントローラーのホスト全体があり、この動作が正しいことが標準であると想定します。私は今、以下を行う少数のコントローラーを持っています:
skip_before_filter :my_base_filter, only: [:method1, :method2]
before_action only: [:method1, :method2] do
my_secondary_filter(param1)
end
このコードは私のコントローラの数であり、かつ(だけでなく、かどうかそれが使用中で渡された方法ということを考えるonly
かexcept
)は、次の1つのコントローラと異なっている、私は理想的に希望の単一持っているbefore_action
かbefore_filter
ということを私はそれが上記のコードを効果的に実行するだろうと呼ぶことができます。継承されたコントローラーでの呼び出しは、理想的には次のようになります。
replace_filter(param1, {only: [:method1, :method2]})
2番目のパラメーター(適用するメソッドの詳細を示すハッシュ)は、空の値を受け入れてすべてのメソッドに適用できる必要があります。私は(これらの他のフィルターと一緒に書かれている)ヘルパー関数を作成しましたが、構文的および論理的にこれを行う必要がありますが、before_action
またはbefore_filter
を使用して、またはmy_base_filter
最初に実行せずに正しく呼び出すことができないようです。これに似たようなことをすることは可能ですか?もしそうなら、そうするための最良の方法は何ですか?
application_controller.rb
class ApplicationController < ActionController::Base
include ApplicationHelper
before_action :my_base_filter
...
end
継承されたコントローラー.rb
class InheritedController < ApplicationController
# I want to replace these lines with my new helper function
skip_before_filter :my_base_filter, only: [:method1, :method2]
before_action only: [:method1, :method2] do
my_secondary_filter(param1)
end
...
end
application_helper.rb
class ApplicationHelper
def my_base_filter
# Do shit here that is the normal behavior
end
def my_secondary_filter(param1)
# Do shit here that is specific to certain functions INSTEAD
# of running the normal base filter
end
# I want to be able to simply call this function
# as a before_action or before_filter in order
# to DRY up my code
def replace_filter(param1, methods = {})
# Run validation on parameters (including methods) here
# including raising exceptions if necessary
...
# Then run the following
skip_before_filter :my_base_filter, methods
before_action(methods) do
my_secondary_filter(param1)
end
end
end
だから... Railsには懸念と呼ばれるものがあります。これは、Railsでモジュールを引き出す方法でありながら、使用できる多数のneatoのものを許可することを目的としています。
それらが何であるか、そしてそれらをどのように使用するかについての記事がたくさんあります。探検させてあげましょう。
以下があなたの問題を解決するかどうかは確かではありませんが、それが私がそれに取り組む方法です。
問題の一部は、あなたが言うように、「replace_filter」メソッドを実行するまでに、bas_filterメソッドがすでに実行されていることです。
必要なのは、ApplicationHelperがコントローラーに初めて含まれるときにreplace_filterを実行できるようにすることです。
ここで、ActiveSupport::Concern
のincluded
方法が役に立ちます。
このようなものを試してみてください:
# give this a meaningful name...
class FilterStuff < ActiveSupport::Concern
included do
puts "I'm in included"
# note: not the replace_filter, but the method that will call it
if defined?(:replace_filter_method)
puts "This controller defines replace filter method which I'm now calling"
replace_filter_method
else
puts "this controller does not define the replace method and will default to base behaviour"
before_action :my_base_filter
end
end
def my_base_filter
puts "I'm in my base filter"
end
def my_secondary_filter(param1)
puts "I'm in secondary filter with param: #{param1}"
end
# making this work is another problem...
def replace_filter(param1, methods = {})
puts "I'm in replace filter with: #{param1} and #{methods.inspect}"
# Run validation on parameters (including methods) here
# including raising exceptions if necessary
...
# Then run the following
skip_before_filter :my_base_filter, methods
before_action(methods) do
my_secondary_filter(param1)
end
end
end
class InheritedController < ApplicationController
include FilterStuff
# actions go here...
private
# define this method only on controllers that need it
def replace_filter_method
puts "I'm in this controllers replace filter method"
replace_filter(param1, only: [:method1, :method2])
end
end
たくさんのprintfデバッグを追加しました-実行トラフがあり、いつ呼び出されているかがわかります-これは、適切なものを機能させるために何をする必要があるかを判断するのに役立ちます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加