view snippets

How to render a view or partial from a Rake task, model or anywhere

Tagged actionview, render, rake, view, rails, routes  Languages ruby

This is tested with Rails 3.0.7 and will most likely change in future versions of Rails:

# @newsletter in the view file
assigns = { :newsletter => self }

routes = Rails::Application.routes # Rails => YourApp
routes.default_url_options = { :host => 'xxx.com' }

av = ActionView::Base.new(Rails::Application::Configuration.new(Rails.root).paths.app.views.first, assigns)
av.class_eval do
  include ApplicationHelper
  include routes.url_helpers
end

self.html = av.render :template => 'newsletters/show'

After some experimentation I ended up with this code:

class RenderHelper
  class << self
    def render(assigns, options, request = {})
      request = { 
        "SERVER_PROTOCOL" => "http", 
        "REQUEST_URI" => "/",
        "SERVER_NAME" => "localhost", 
        "SERVER_PORT" => 80
      }.merge(request)

      av = ActionView::Base.new(ActionController::Base.view_paths, assigns)
      
      av.config = Rails.application.config.action_controller
      av.extend ApplicationController._helpers
      av.controller = ActionController::Base.new
      av.controller.request = ActionController::Request.new(request)
      av.controller.response = ActionController::Response.new
      av.controller.headers = Rack::Utils::HeaderHash.new

      av.class_eval do
        include Rails.application.routes.url_helpers
      end

      av.render options 
    end
  end
end

And this is how I use it:

RenderHelper.render(:newsletter => self, :template => 'mailchimp/daily')

How to prepend a directory to the view path in Rails (3, 4, etc)

Tagged prepend_view_path, view, paths, rails  Languages ruby

prepend_view_path is your friend when you want to use different views in the same app for different configurations, e.g. same code for different apps/sites/etc:

class ApplicationController ....
   prepend_view_path Rails.root.join('app', 'views', ENV['APP'])
end

prepend_view_path can also be called e.g. once per request before rendering the view to have different view templates for each subdomain, user, cat, etc.