Reputation: 91
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?
Upvotes: 6
Views: 1989
Reputation: 12550
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
Upvotes: 1
Reputation: 2476
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
Upvotes: 2
Reputation: 893
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
Upvotes: 0
Reputation: 11609
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, ...})
Upvotes: -1