Rails:从外部控制器渲染视图

时间:2015-02-04 22:20:55

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

我尝试使用视图创建HTML字符串。我想从一个不是控制器的类中渲染它。如何在控制器外部使用rails渲染引擎?与ActionMailer的工作方式类似?

谢谢!

8 个答案:

答案 0 :(得分:36)

Rails 5现在以更方便的方式支持这个,处理创建请求以及幕后的东西:

rendered_string = ApplicationController.render(
  template: 'users/show',
  assigns: { user: @user }
)

这会呈现app/views/users/show.html.erb并设置@user实例变量,因此您无需对模板进行任何更改。它会自动使用ApplicationController中指定的布局(默认情况下为application.html.erb)。

The test shows a handful of additional options and approaches.

答案 1 :(得分:35)

您可以使用ActionView::Base来实现此目标。

view = ActionView::Base.new(ActionController::Base.view_paths, {})
view.render(file: 'template.html.erb')

ActionView::Base初始化需要:

  1. 表示模板搜索路径的上下文
  2. assigns哈希,提供模板的变量
  3. 如果您想包含帮助程序,可以使用class_eval包含它们:

    view.class_eval do
      include ApplicationHelper
      # any other custom helpers can be included here
    end
    

答案 2 :(得分:4)

没有必要用太多宝石过度膨胀你的应用程序。我们知道ERB已经包含在您的Rails应用程序中。

@jdf = JDF.new
@job = ERB.new(File.read(Rails.root + "app/views/entries/job.xml.erb"))
result =  @job.result(binding)

上面有我正在处理的应用程序代码片段。

  • @jdf是要在erb视图中评估的对象。
  • 就我而言,我需要渲染xml
  • result是一个要保存或发送到任何您喜欢的地方的字符串。

答案 3 :(得分:1)

从技术上讲,ActionMailerAbstractController::Base的子类实现。如果您想自己实现此功能,您可能也希望继承AbstractController::Base

这里有一篇很好的博文:https://www.amberbit.com/blog/2011/12/27/render-views-and-partials-outside-controllers-in-rails-3/,解释了所需的步骤。

答案 4 :(得分:1)

在ApplicationController上直接调用render方法可能会引发错误

 Helper Devise: could not find the `Warden::Proxy` instance on request environment

相反,我们可以像

一样使用ApplicationController.renderer.render。
 rendered_string = ApplicationController.renderer.render(
     partial: 'users/show',
     locals: { user: user }
)

答案 5 :(得分:0)

“我正在尝试使用视图创建HTML字符串。” - 如果您的意思是您在视图模板的上下文中,那么只需使用辅助方法或渲染部分方法。

如果您使用其他“普通旧Ruby对象”,请记住您可以直接使用ERB模块:

erb = ERB.new("path/to/template")
result = erb.result(binding)

诀窍是获取“绑定”对象,该对象为模板中的代码提供上下文。 ActionController和其他Rails类免费公开它,但我找不到一个引用来解释它的来源。

http://www.ruby-doc.org/stdlib-2.2.0/libdoc/erb/rdoc/ERB.html#method-i-result

答案 6 :(得分:0)

为了将来的参考,我最终找到了 这个方便的宝石让这变得轻而易举:

https://github.com/yappbox/render_anywhere

答案 7 :(得分:0)

最好使用控制器渲染视图,因为这就是它们的用途,然后将其转换为字符串,因为这是您的最终目标。

require 'open-uri'
html = open(url, &:read)