Accessing URL Helpers when Rendering Partials from Rails Models
Asked Answered
R

4

6

I have to render some templates and send the HTML block to SendGrid for email substitution. So, unfortunately, I am doing some rendering in model like this:

    view = ActionView::Base.new(Rails.configuration.paths["app/views"].first)
    view.render(:partial => template_name)

Even if I added:

    view.extend Rails.application.routes.url_helpers
    view.extend ActionView::Helpers::UrlHelper
    view.extend ApplicationHelper

The partial don't have access to URL Helpers like url_for unless I explicit define the module like in the following:

    Rails.application.routes.url_helpers.edit_user_url(user, :host => Rails.application.config.action_mailer.default_url_options[:host])

Is there a cleaner way to use URL Helper in templates called from models?

Ritz answered 7/12, 2013 at 5:20 Comment(1)
Have you solved this issue? I am currently digging the same problem and nothing useful unfortunately.Headward
C
2

In Rails 5, it is simple:

ApplicationController.render partial: 'my/partial'

It will have all your helpers loaded

more info: https://evilmartians.com/chronicles/new-feature-in-rails-5-render-views-outside-of-actions

Chatterton answered 23/4, 2018 at 21:36 Comment(0)
C
1

A workaround I found is to pass the url_helpers as part of the locals:

url = Rails.application.routes.url_helpers
view = ActionView::Base.new(Rails.configuration.paths['app/views'].first)
view.render(partial: template, locals: locals.merge(url: url))

and then in the view:

<%= url.thing_path %>

Also note you must to configure your default_url_options with:

# config/environments/production.rb
  config.after_initialize do
    Rails.application.routes.default_url_options = { host: 'production.server.com' }
  end

# config/environments/development.rb
  config.after_initialize do
    Rails.application.routes.default_url_options = { host: 'localhost', port: 3000 }
  end
Cascade answered 12/5, 2017 at 3:30 Comment(0)
L
0

this is my solution

options = Rails.configuration.action_mailer.default_url_options
view = ApplicationController.renderer.new(http_host: "#{options[:host]}:#{options[:port]}")
view.class_eval do       
  include Rails.application.routes.url_helpers
  include ApplicationHelper

  def protect_against_forgery?
    false
  end
end
view.render partial: "mailers/#{name.to_s}", layout:false
Lunn answered 23/4, 2018 at 14:5 Comment(0)
L
-1

Hi to access urls inside the views, you can do something like

view = ActionView::Base.new(Rails.configuration.paths["app/views"].first)
view.extend ApplicationHelper

and then

template =  view.render(file: '#_file',:locals => { #_path: #_path, ...})
Locklear answered 19/6, 2014 at 8:34 Comment(1)
But this is almost the same the OP put as example in the questionCascade

© 2022 - 2024 — McMap. All rights reserved.