Rails: Render view from outside controller

前端 未结 8 2145
不思量自难忘°
不思量自难忘° 2020-12-15 03:41

I\'m trying to create an HTML string using a view. I would like to render this from a class that is not a controller. How can I use the rails rendering engine outside a co

相关标签:
8条回答
  • 2020-12-15 03:59

    Technically, ActionMailer is a subclass implementation of AbstractController::Base. If you want to implement this functionality on your own, you'll likely want to inherit from AbstractController::Base as well.

    There is a good blog post here: https://www.amberbit.com/blog/2011/12/27/render-views-and-partials-outside-controllers-in-rails-3/ that explains the steps required.

    0 讨论(0)
  • 2020-12-15 04:00

    Rails 5 now supports this in a much more convenient manner that handles creating a request and whatnot behind the scenes:

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

    This renders app/views/users/show.html.erb and sets the @user instance variable so you don't need to make any changes to your template. It automatically uses the layout specified in ApplicationController (application.html.erb by default).

    The test shows a handful of additional options and approaches.

    0 讨论(0)
  • 2020-12-15 04:10

    Best to render the view using a controller, as that's what they're for, and then convert it to a string, as that is your ultimate goal.

    require 'open-uri'
    html = open(url, &:read)
    
    0 讨论(0)
  • 2020-12-15 04:11

    There is no need to over bloat your app with too many gems. As we know ERB is already included in your Rails app.

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

    Above there is snippet of code of an app I'm working on.

    • @jdf is a object to be evaluated in the erb view.
    • In my case I needed to render xml.
    • result is a string to be saved or sent anywhere you like.
    0 讨论(0)
  • 2020-12-15 04:15

    You can use ActionView::Base to achieve this.

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

    The ActionView::Base initialize takes:

    1. A context, representing the template search paths
    2. An assigns hash, providing the variables for the template

    If you would like to include helpers, you can use class_eval to include them:

    view.class_eval do
      include ApplicationHelper
      # any other custom helpers can be included here
    end
    
    0 讨论(0)
  • 2020-12-15 04:15

    Calling directly render method on ApplicationController may raise error

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

    Instead we can use ApplicationController.renderer.render like

     rendered_string = ApplicationController.renderer.render(
         partial: 'users/show',
         locals: { user: user }
    )
    
    0 讨论(0)
提交回复
热议问题