【问题标题】:calling a controller action with argument from rack middleware使用机架中间件的参数调用控制器操作
【发布时间】:2012-04-09 11:48:51
【问题描述】:

有没有办法可以将参数从中间件传递给控制器​​操作调用?

这是控制器代码中的动作

# 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

我不知道如何将参数传递给action 调用。这是来源:

# 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

这看起来很脏,我想知道更好的方法。谢谢。

【问题讨论】:

  • 无论您尝试做什么,都必须有更好的方法。如果您可以为最终要完成的工作提供更多背景信息,那么可能会有一个更简单的解决方案。
  • 我试图在抛出异常后重定向到特定的控制器操作。基本上它是空气制动宝石的fix。很难找到从中间件调用控制器方法的例子。不过,感谢您的评论。

标签: ruby-on-rails ruby rack


【解决方案1】:

你不想为你的行为提出论据。中间件应该只与请求环境交互,而不是尝试直接调用控制器。

您可以在 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

【讨论】:

  • 是的,我注意到这是错误的做法。它在 rails 2.x 中是这样实现的,因为它在 ActionController 中定义了一个 rescue_action_in_public(exception),并且这个方法是它的别名。我试图在不改变方法调用的情况下为 rails 3.x 实现相同的行为。不过感谢您的回答 -> 接受、支持和赏金 :)
  • 谢谢。欢迎您在 gmail 或 gchat 上通过 winfield.peterson 给我发送电子邮件以进一步交谈。您可能能够将异常处理/报告提取到帮助程序类中,并在中间件和控制器中使用它。如果它具有特定于控制器的重定向逻辑或其他内容,您可以将其放在一个块中吗?很高兴结束完整解决方案的循环。
猜你喜欢
  • 1970-01-01
  • 2010-11-27
  • 2015-08-24
  • 1970-01-01
  • 1970-01-01
  • 2015-11-22
  • 2019-06-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多