【问题标题】:Execute arbitrary rails 4 controller action, render to string执行任意 rails 4 控制器动作,渲染到字符串
【发布时间】:2014-10-06 13:46:05
【问题描述】:

在 Rails 4 中,如何执行任意控制器操作并将响应呈现给字符串?

这显然是一种不好的做法,但在某些情况下很难避免:

  • 您正在制作动态呈现的 pdf(或任何独立响应)的离线副本或电子邮件附件。
  • 上述响应涉及不受您控制或在外部 gem 中的视图和控制器。
  • 上述视图涉及布局和数十个使用相对路径和自定义模板渲染引擎的局部视图。

在某些情况下(当从另一个控制器调用时),可以通过替换视图所需的任何数据来消除对控制器的依赖。但是,这通常仍然会破坏视图渲染,因为不能再将相对路径传递给部分内的渲染函数(以及其他问题)。

【问题讨论】:

  • 你渲染这个任意动作的上下文是什么?在另一个动作中?从控制台?耙任务?如果您想要相同的输出(例如 render new 如果 create 失败),则在同一控制器中相对常见。
  • 来自 ActionMailer 控制器和集成测试。

标签: ruby-on-rails ruby-on-rails-4 actionmailer renderpartial


【解决方案1】:

所以我实际上并没有这样做。或者类似的东西。

但我记得你可以为任意 Rails 操作获取一个 Rack 应用程序对象。因此,您似乎可以使用该 rack-compat 接口来执行所有任意操作并在内部获得响应,而无需实际发出 http 请求。

谷歌搜索了我模糊记得的东西,把它们拼凑在一起,得到了这个,我在我制作的一个非常简单的虚拟应用程序中进行了尝试,它似乎有效:

rack_env = Rack::MockRequest.env_for("/some/url?foo=bar")
rack_app = SomeController.action(:index)

(status, headers, rack_body) = rack_app.call(rack_env)
str = rack_body.body

我很惊讶需要在我已经认为是身体的东西上调用#body,不确定到底发生了什么我想我并不完全了解 rack api。不确定 MockRequest 是否是构建请求的正确方法。不确定是否有更好的方法(但是 3-4 行也不错)。但它似乎确实有效。

(可能还有一种方法可以让“正确”的工作方式也有足够的工作量——例如,有一些方法可以更改或添加到视图模板查找路径,将原始控制器的视图放在视图查找中路径,即使您从新视图渲染模板。但我相信您会很痛苦,老实说,在这种情况下,我不确定“正确”的做法是什么,我认为 em> Rack 方法似乎是合理的)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-16
    • 2015-12-15
    • 1970-01-01
    • 2010-11-17
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    相关资源
    最近更新 更多