Ruby on Rails
HowtoUseUrlHelpersWithActionMailer

ActionMailer does not work with the URL helpers (like url_for and @link_to@) automatically, because those helpers depend on a reference to the current controller. However, you can very easily make those helpers work with your mailers.

First, define your mailer method such that it accepts a controller instance as a parameter, and passes it to the body:

<pre> class MyMailer < ActionMailer::Base ... def send_urls(controller, to) subject "Sending some URLs..." from "myapp @ example.com" recipients to body :controller => controller end ... end </pre>

Then, you need to add the helper reference to your mailer. You need to give the complete reference to the module currently (this might change eventually, though):

<pre> class MyMailer < ActionMailer::Base ... helper ActionView::Helpers::UrlHelper ... end </pre>

Now, you can use the url_for helper in your mailer views:

<pre> Here is my mailer view! Have some url's, on me:

* <%= url_for :controller => “foo” %> * <%= url_for :action => “slurpy” %> * <%= url_for :some_named_url %>


You just need to remember to pass the controller instance first when invoking this mailer method:

<pre> def some_action ... MyMailer.deliver_send_urls(self, "<a href="mailto:recip@example.com">recip@example.com</a>") ... end </pre>

Note: It may be easier, and more extensible, to just pass a hash of all the options you want directly to the mailer method:

<pre> def some_action ... MyMailer.deliver_send_urls(:controller => "self", :to => "recip @ example.com") ... end </pre>

Then, in your mailer, you can just take that hash and assign it directly to the body:

<pre> class MyMailer < ActionMailer::Base ... def send_urls(params) subject "Sending some URLs..." from "myapp @ example.com" recipients params[:to] body params end ... end </pre>

It’s all up to you.

Question: How do you use ActionMailer from script/runner, Rake tasks, tests, etc?

One way to test action mailers is to mock out the controller using Openstruct.
<pre> require 'ostruct'

class Controller < OpenStruct
def url_for(options)
return “/some/url”
end
end
class MailerTest < Test::Unit::TestCase
def test_invite

controller = Controller.new
invitation = invitations(:joey)
response = Mailer.create_invitation(invitation,controller)

assert_equal(“Please check out my website!” , response.subject)

end
end




category:Howto