How to generate correct URLs in mailer templates? - ruby-on-rails

I am using Ruby on Rails 3.1.0 and I would like to properly generate URLs in HTML email messages. In my environment file I set
config.action_mailer.default_url_options = { :host => 'my_site.org' }
In the email view file (.html.erb) I state
<%= link_to #user.name, users_url(#user) %>
When I go to see the received email the generated URL is http://users/1, of course no correct. So, how can I generate correct URLs in mailer templates so to have http://my_site.org/users/1 links in body messages?
I also tryed to set the default_url_options in my mailer.rb file
class MyCustom::Mailer < ActionMailer::Base
default_url_options[:host] = 'my_site.org'
def test_sending
...
end
end
but it doesn't work.

users_path is the relative path (/users/1). For an email, you want the absolute path, so use users_url(#user), which will give http://myapp.com/users/1 instead.

your action_mailer setting is correct.
But you should be using _url and not _path for the link_to,
<%= link_to #user.name, users_url(#user) %>

See that you set the config option. To be sure it uses the absolute path use:
<%= link_to, "My Profile", users_url(:only_path => false, #user) %>
OR set the host specifically in the link:
<%= link_to, "My Profile", users_url(:host => "example.com", #user) %>
It is explained here:
ActionView Helpers

Related

How can I get the base url in an ActionMailer?

I want to send out an email with a deep link back into my app, but I'd rather not have to hard-code the URL or else I have to switch it when I move from one environment to the next. How can I obtain the base url of a web app from within an ActionMailer? For example, I'd love to be able to have something like:
<%= base_uri %>listCreate?first=foo&second=bar
render something like the following in my testing environment:
http://localhost:30000/myApp/listCreate?first=foo&second=bar
and the following in production:
http://www.myDomain.com/myApp/listCreate?first=foo&second=bar
Set the defult url option in config/environments/production.rb
config.action_mailer.default_url_options = { :host => 'your.app.com' }
and in mail template
the link should be
<%= link_to 'myapp', myapp_list_url %>
Hope this could help
You can refer the Action Mailer doc
You can set the default_url_options for your mailer in the controller where you have the current host for the request.
In my case, I send an email when I receive information in some lead creation form, so I have a LeadMailer. My solution was to create a before filter to set the host in the mailer.
Of course, you don't need to do it in a before filter, you could set it in your action.
My solutions looked like this:
class LeadsController < ApplicationController
before_action :set_host, on: [:create]
def set_host
LeadsMailer.default_url_options = { host: request.host_with_port }
LeadsMailer.asset_host = request.protocol + request.host_with_port
end
end
I set the asset_host config because I wanted to use my images from the assets pipeline.
Now you can use the _url helpers as usual
<%= link_to 'something', something_url %>
Or your asset helpers
<%= image_url('logo.png')%>

Rails - ActionMailer view: how do I link to a file in my public folder

I want to send an email to a user with a link to download a PDF file in my public folder. How do I create the link from within an ActionMailer view? I need a solution that will work in my Test, Development, and Production environments (so, no hard coded links).
If you already have a route that you use in a normal view, then you can just replace _path with _url.
If you are building a custom link, then just use the root_url variable in a string which will print out: http://yourhost.com/
eg for HTML emails, assuming a filename variable
<%= link_to 'Download PDF', "#{root_url}#{filename}" %>
for Text emails:
<%= "#{root_url}#{filename}" %>
Make sure you set your correct host name for each environment in your config/environments/ENV.rb as this is where the _url gets its hostname from
eg: config/environments/production.rb
config.action_mailer.default_url_options = { :host => 'yourhost.com' }

How can I create link to the json-view of an object in Rails?

What do I need to change in the code below to make it link to a view rendered as json?
<%= link_to 'JSON Link', #mymodel %>
So I'd like to generate the following url
http://localhost:3000/mymodels/1.json
instead of
http://localhost:3000/mymodels/1
(These urls both work as expected.)
To do this, you must specify the format:
<%= link_to 'JSON Link', your_model_path(#mymodel, :format => 'json') %>
The URL helper methods can be retrieved by running:
rake routes
The first column is the name of the helper method, on which you should append either _path or _url, the latter will generate an absolute URL.
More information is in the Guide To Rails Routing

Absolute URL's with link_to...Ruby on Rails

Is it possible to generate absolute URL's in rails using link to? [NOTE: THIS IS IN A MAILER]
I tried to do:
<%= link_to root_url, root_url%>
But I get a runtime error:
*Missing host to link to! Please provide :host parameter or set default_url_options[:host]*
I need this to be dynamic because the application will run on a wildcard domain (*.domain.com)
If you use the _url suffix, the generated URL is absolute. Use _path to get a relative URL.
<%= link_to "Home", root_url %>
<%= link_to "Home", root_path %>
Depending on your use case, string interpolation might be a good solution:
link_to(body, "http://#{site_url}")
I found this plugin:
http://www.simonecarletti.com/blog/2009/10/actionmailer-and-host-value/
and it works great!
In routes.rb insert :
root :to => 'controller#action'
Or replace your current map.root with the correct one.
See documentation about this : routes.rb usage

Problem with url_for and named routes in ActionMailer View: "Need controller and action"

I'm attempting to provide a confirmation link in my user welcome email and I'm getting the following Rails error:
Need controller and action!
It makes a fuss about this line:
<p>Please take a moment to activate your account by going to:
<%= link_to confirm_user_url(:id => #user.confirmation_code) %>.</p>
In my development.rb environment, I have the following line:
config.action_mailer.default_url_options = {
:host => "localhost", :port => 3000
}
There's no problem with the #user variable. I've tested the email with things like #user.username and #user.confirmation_code. I'm only getting trouble with url_for and named routes like confirm_user_url.
When I check my routes with rake routes, confirm_user shows up, so it's not an issue with the named route not existing.
I can't seem to figure it out. What gives?
ActionMailer isn't a real Rails controller, so routes aren't available in your mailer templates. You need to set up instance variables in your mailer class to pass values to the template.
eg. if your mailer is SampleMailer:
class SampleMailer < ActionMailer::Base
def confirmation_mail(user)
subject 'Confirmation'
recipients user.email
from 'sample#example.com'
sent_on Time.now
body :greeting => 'Sample Greeting', :email => user.email,
:confirm_user_url => confirm_user_url(:id=>#user.confirmation_code)
end
end
Then in the template:
<%= link_to "Confirmation link", #confirm_user_url %>
This is explained somewhat cryptically in the api in the "ActionMailer" section, and in more detail in Agile Web Development with Rails, 3rd Ed., Chapter 25.
Since having a clickable url is what you said in your where after in your comment, here you go macek
<p>Please take a moment to activate your account by going to:
<%= auto_link confirm_user_url(:id => #user.confirmation_code) %>.</p>
I've used the auto_link helper in some of my mailers to make urls clickable and it has worked out pretty well. I think that does email addresses also, check out the full api for all the options. Enjoy.

Resources