views:

229

answers:

2

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?

+2  A: 

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       '[email protected]'
    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.

zetetic
@zetetic, this was less of a strange problem than I thought. The issue wasnt' that I was using `confirm_user_url()` in the ActionMailer View, it was because I was only specifying one argument to `link_to`. I needed to specify `link_to confirm_user_url(:id => @user.confirmation_code), confirm_user_url(:id => @user.confirmation_code)`. Because that's hideous, I used part of your method so I can just use `link_to @confirm_link, @confirm_link`. Thanks for the help.
macek
I thought my answer was well-written, well-researched and concise. I see now that it also missed the point :)
zetetic
@zetetic, yeah, it still helped me get to where I wanted to be so I gave you a +1.
macek
+1  A: 

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.

Corey