呈现来自rake任务的视图(带有部分视图)

时间:2022-05-21 20:18:45

I got the following code in a rake task:

我在rake任务中得到了以下代码:

class PdfExporter < ActionView::Base
  include Rails.application.routes.url_helpers
  include ActionView::Helpers::TagHelper
  include ActionView::Helpers::UrlHelper

  def generate_pdf_from_html  
    content = File.read('path/to/view.html.erb')
    erb = ERB.new(content)
    html_content = erb.result(binding)

    # ... some pdf stuff
  end
end

The problem - the said view.html.erb is rendering another view in it.

问题-上面说的view.html。erb正在渲染另一个视图。

  <%= render partial: 'path/to/another_view' %>

And erb.result(binding) is throwing the following error:

而erb.result(binding)抛出如下错误:

Missing partial /path/to/another_view

缺失的部分/道路/ / another_view

If there are no partials, the view renders fine.

如果没有分区,视图就会呈现良好。

I'm sure that the path is right, but seems that I can't render it from a rake task.

我确信这条路径是正确的,但似乎我无法从rake任务中渲染它。

Why? Can I include some useful helper?

为什么?我可以提供一些有用的帮助吗?

I don't want to instantiate controllers.

我不想实例化控制器。

EDIT:

编辑:

Searched in:

is empty. Probably means that the ActionView don't 'know' where to search for the view.

是空的。可能意味着ActionView不知道在哪里搜索视图。

1 个解决方案

#1


3  

Here is an example of a rake task I have that creates an html file from a view. For it to work, you have to appease ActionView by overriding some defaults and by passing in a fake controller and request:

这里有一个从视图创建html文件的rake任务示例。为了让它工作,你必须通过重写一些默认值来满足ActionView,并通过一个假控制器和请求:

  desc 'Example of writing a view to a file'
  task :example => :environment do

    # View that works with Rake
    class RakeActionView < ActionView::Base
      include Rails.application.routes.url_helpers
      include ::ApplicationHelper
      # Include other helpers that you will use

      # Make sure this matches the expected environment, e.g. localhost for dev
      # and full domain for prod
      def default_url_options
        {host: 'localhost:3000'}
      end

      # It is safe to assume that the rake request is legit
      def protect_against_forgery?
        false
      end
    end

    # build a simple controller to process the view
    controller = ActionController::Base.new
    controller.class_eval do
      include Rails.application.routes.url_helpers
      include ::ApplicationHelper
    end

    # build a fake request
    controller.request = ActionDispatch::TestRequest.new

    # build the rake view with the path to the app views
    view = RakeActionView.new(Rails.root.join('app', 'views'), {}, controller)

    # example assigning instance @variables to the view
    view.assign( :user => User.first )

    # Render the view to html
    html = view.render(template: 'relative/path/to/template', layout: 'layouts/example')

    # Write html to temp file and then copy to destination
    temp = Tempfile.new('example_file')
    temp.write(html)
    FileUtils.cp( temp.path, 'path/to/exmple_file' )

    # optionally set permissions on file
    File.chmod(0774, 'path/to/exmple_file')

    # close up the temp file
    temp.close
    temp.unlink
  end

Looks like the issue you are having is fixed by RakeActionView.new(Rails.root.join('app', 'views'), {}, controller) which sets the path that ActionView looks for templates.

看起来您遇到的问题是通过RakeActionView.new(Rails.root)解决的。join('app', 'views'), {}, controller)设置ActionView查找模板的路径。

#1


3  

Here is an example of a rake task I have that creates an html file from a view. For it to work, you have to appease ActionView by overriding some defaults and by passing in a fake controller and request:

这里有一个从视图创建html文件的rake任务示例。为了让它工作,你必须通过重写一些默认值来满足ActionView,并通过一个假控制器和请求:

  desc 'Example of writing a view to a file'
  task :example => :environment do

    # View that works with Rake
    class RakeActionView < ActionView::Base
      include Rails.application.routes.url_helpers
      include ::ApplicationHelper
      # Include other helpers that you will use

      # Make sure this matches the expected environment, e.g. localhost for dev
      # and full domain for prod
      def default_url_options
        {host: 'localhost:3000'}
      end

      # It is safe to assume that the rake request is legit
      def protect_against_forgery?
        false
      end
    end

    # build a simple controller to process the view
    controller = ActionController::Base.new
    controller.class_eval do
      include Rails.application.routes.url_helpers
      include ::ApplicationHelper
    end

    # build a fake request
    controller.request = ActionDispatch::TestRequest.new

    # build the rake view with the path to the app views
    view = RakeActionView.new(Rails.root.join('app', 'views'), {}, controller)

    # example assigning instance @variables to the view
    view.assign( :user => User.first )

    # Render the view to html
    html = view.render(template: 'relative/path/to/template', layout: 'layouts/example')

    # Write html to temp file and then copy to destination
    temp = Tempfile.new('example_file')
    temp.write(html)
    FileUtils.cp( temp.path, 'path/to/exmple_file' )

    # optionally set permissions on file
    File.chmod(0774, 'path/to/exmple_file')

    # close up the temp file
    temp.close
    temp.unlink
  end

Looks like the issue you are having is fixed by RakeActionView.new(Rails.root.join('app', 'views'), {}, controller) which sets the path that ActionView looks for templates.

看起来您遇到的问题是通过RakeActionView.new(Rails.root)解决的。join('app', 'views'), {}, controller)设置ActionView查找模板的路径。