6

ミドルウェアからコントローラーアクション呼び出しに引数を渡す方法はありますか?

これはコントローラーコードのアクションです

# in my_controller.rb
# 
def print_name(name)
    render :text => "Hello, #{name}!"
end

このアクションを呼び出すミドルウェアのコードは次のとおりです

# in middleware
#
def call(env)
  env['action_controller.instance'].class.action(:print_name).call(env)
end

これはもちろん を上げArgumentErrorます。

actioncallに引数を渡す方法がわかりません。ソースは次のとおりです。

# in action_pack/lib/action_controller/metal.rb
#
def self.action(name, klass = ActionDispatch::Request)
      middleware_stack.build(name.to_s) do |env|
        new.dispatch(name, klass.new(env))
      end
end

ご覧のとおり、提供されたコントローラー アクションからラック エンドポイントを返します。ここで引数を渡す方法がわかりません。

私はコントローラを動的に変更し、class_evalそのプロキシメソッドからコントローラメソッドを呼び出すことになりました。

# in middleware
#
def define_proxy_method(klass)
      klass.class_eval do
            def call_the_real_method
              print_name(request.env['fake_attribute'])
            end
      end
 end

def call(env)
  define_proxy_method(env['action_controller.instance'].class)
  env['fake_attrbute'] = "Yukihiro"
  env['action_controller.instance'].class.action(:call_the_real_method).call(env)
end

これは汚いようで、より良い方法を知りたいです。ありがとう。

4

1 に答える 1

4

自分の行動に議論を加えたくありません。ミドルウェアはリクエスト環境とのみやり取りし、コントローラーを直接呼び出そうとしないでください。

params ハッシュで同じ値を渡すことができます。

# middleware
#
def call(env)
  request = Rack::Request.new(env)
  request['name'] = get_name
end

コントローラーの params ハッシュから読み取ります。

# my_controller.rb
# 
def print_name
    render :text => "Hello, #{params['name']}!"
end
于 2012-04-16T17:34:31.943 に答える