New ActionMailer API in Rails 3.0
Tue Jan 26 12:13:00 -0800 2010
Action Mailer has long been the black sheep of the Rails family. Somehow, through many arguments, you get it doing exactly what you want. But it takes work! Well, we just fixed that.
Action Mailer now has a new API.
But why? Well, I had an itch to scratch, I am the maintainer for TMail, but found it very hard to use well, so I sat down and wrote a really Ruby Mail library, called, imaginatively enough, Mail
But Action Mailer was still using TMail, so then I replaced out TMail with Mail in Action Mailer
And now, with all the flexibility that Mail gives us, we all thought it would be a good idea to re-write the Action Mailer DSL. So with a lot of ideas thrown about between David, Yehuda and myself, we came up with a great DSL.
I then grabbed José Valim to pair program together (with him in Poland to me in Sydney!) on ripping out the guts of Action Mailer and replacing it with a lean, mean mailing machine.
This was merged today.
So what does this all mean? Well, code speaks louder than words, so:
Creating Email Messages:
Instead of this:
class Notifier < ActionMailer::Base
def signup_notification(recipient)
recipients recipient.email_address_with_name
subject "New account information"
from "system@example.com"
content_type "multipart/alternative"
body :account => recipient
part :content_type => "text/html",
:data => render_message("signup-as-html")
part "text/plain" do |p|
p.body = render_message("signup-as-plain")
p.content_transfer_encoding = "base64"
end
attachment "application/pdf" do |a|
a.body = generate_your_pdf_here()
end
attachment :content_type => "image/jpeg",
:body => File.read("an-image.jpg")
end
end
You can do this:
class Notifier < ActionMailer::Base
default :from => "system@example.com"
def signup_notification(recipient)
@account = recipient
attachments['an-image.jp'] = File.read("an-image.jpg")
attachments['terms.pdf'] = {:content => generate_your_pdf_here() }
mail(:to => recipient.email_address_with_name,
:subject => "New account information")
end
end
Which I like a lot more :)
Any instance variables you define in the method become available in the email templates, just like it does with Action Controller, so all of the templates will have access to the @account instance var which has the recipient in it.
The mail method above also accepts a block so that you can do something like this:
def hello_email
mail(:to => recipient.email_address_with_name) do |format|
format.text { render :text => "This is text!" }
format.html { render :text => "<h1>This is HTML</h1>" }
end
end
In the same style that a respond_to block works in Action Controller.
Sending Email Messages:
Additionally, sending messages has been simplified as well. A Mail::Message object knows how to deliver itself, so all of the delivery code in Action Mailer was simply removed and responsibility given to the Mail::Message.
Instead of having magic methods called deliver_* and create_* we just call the method which returns a Mail::Message object, and you just call deliver on that:
So this:
Notifier.deliver_signup_notification(recipient)
Becomes this:
Notifier.signup_notification(recipient).deliver
And this:
message = Notifier.create_signup_notification(recipient) Notifier.deliver(message)
Becomes this:
message = Notifier.signup_notification(recipient) message.deliver
You still have access to all the usual types of delivery agents though, :smtp, :sendmail, :file and :test, these all work as they did with the prior version of ActionMailer.
Receiving Emails
This has not changed, except now you get a Mail::Message object instead of a TMail object.
Mail::Message will be getting a :reply method soon which will automatically map the Reply related fields properly. Once this is done, we will re-vamp receiving emails as well to simplify.
Old API
And… of course, if you still “like the old way”, the new Action Mailer still supports the old API and all the old tests still pass. We have moved everything relating to the old API into deprecated_api.rb and this will be removed in a future release of Rails.
Summary
With Mail and this refactor, Action Mailer has now finally become just a DSL wrapper between Mail and Action Controller.
blogLater
Mikel




Mon Jan 25 18:41:31 -0800 2010
Absolutely fantastic news Mikel! Thanks for this!
Mon Jan 25 21:17:06 -0800 2010
Well done. Some top notch work from both yourself and José. Keep it up!
Mon Jan 25 21:28:18 -0800 2010
Method #deliver is pretty good instead of #…_deliver
Mon Jan 25 21:45:49 -0800 2010
It’s not really an accurate model of the real world that a message knows how to deliver itself, although the postal system might be better off if zero-intelligence envelopes all delivered themselves (just a little smarter than the average postal worker!)
Tue Jan 26 00:55:38 -0800 2010
Looks amazing! Does the new API also support inline attachments? Right now I have to use an aweful hack.
Tue Jan 26 01:29:59 -0800 2010
@Chris it should, just pass the :content_disposition => ‘inline’ to the attachments[‘filename’] method…
Try it and let me know :)
Mikel
Tue Jan 26 04:29:21 -0800 2010
I like getting rid of #deliver_* and #create_* magic methods, but replacing methods with hash keys (to, subject, etc.) seems a bit unnatural and against common sense, especially considering the opposite direction of ActiveRecord 3 (:conditions, :limit, etc. becomes #where, #limit, etc.).
Also, the #mail method doesn’t feel too Ruby’ish semantically – of course, it’s a #mail since we’re already in ActionMailer :) – but I imagine that’s a problem with calling the method directly and not wrapping it in #deliver_*.
Tue Jan 26 10:36:34 -0800 2010
I love it! Following the conventions from controller with instance variables and format blocks feels so natural.
Can’t wait to use the new way of inline attachments. My old hacks were ugly.
Thu Jan 28 22:21:21 -0800 2010
Nice! looks like they reside in /app/mailers now — certainly a needed organizational touch.
Thu Jan 28 22:21:27 -0800 2010
Nice! looks like they reside in /app/mailers now — certainly a needed organizational touch.
Wed Jan 27 12:25:23 -0800 2010
Excellent work. Your Mail library has a pretty straightforward feel to it.
In the line:
attachments[‘an-image.jp’] = File.read(“an-image.jpg”)
you missed the “g”. Would the attachment then be delivered to the recipient without the “g” in the filename?
Fri Jan 29 06:15:07 -0800 2010
Good work, I really like the .deliver methods! Is there an easy way to forward a message including attachments?
As of now I have to parse through the message pull out the html body, the plain body, the attachments, and then re-assemble into a coherent message…all so i can just change the “to” field. (hopefully i’m doing this wrong and someone can school me)
Fri Jan 29 11:06:59 -0800 2010
Nice work! I love getting rid of the deliver_blah magic, obj.deliver makes so much more intuitive sense.
I’m very curious, how did you manage to pair program over that distance? Skype screen sharing?
Fri Jan 29 11:20:10 -0800 2010
That’s awesome great work!
BTW, isn’t this wrong?
This is HTML” }format.text { render :text => “
format.html { render :text => “This is text!” }
Should be:
This is HTML” }format.text { render :text => “This is text!” }
format.html { render :text => “
Shouldn’t it?
Fri Jan 29 15:08:03 -0800 2010
@Eduardo, you are right! :) I guess I could say it is there to make sure people read the post, but I will fix it none the less
Mon Feb 01 17:26:23 -0800 2010
awesome…i always thought the deliver_* syntax was weird and much prefer the *.deliver – Well done and thanks guys!!
Tue Feb 23 23:12:35 -0800 2010
Hi Mikel,
Thanks for the great code and update on how to use it. I confess to being stumped by one thing: I have both an html and text version of a template I’d like to use depending on a user’s preference. I thought I could pass a block to the mail call with some sort of logic but no matter what I do, it seems to always create a multipart email.
So, with two files, a.html.haml and a.text.haml in my app/views/notifier folder, what is the correct way to send an email with only one of those templates being used?
Thanks!
Wed Feb 24 00:04:53 -0800 2010
@Jack, though I haven’t tried it, Action Mailer uses the same code that ActionController does, ie, Abstract Controller. So in your mail action, instead of using the default rendering, render a specific template and return, this should do it.
Thu Feb 25 13:12:05 -0800 2010
Thanks Mikel. Just to make sure I’m clear. Should this code only send one type of email (regardless of whether multiple types exist in the directory:
mail(:to => user.email, :subject => “hello”) do |format|
format.html
end
Or are you saying I need to explicitly call render in a block passed to format.html.
Will try this some more tonight but just wanted to make sure I was understanding you before going down this road.
Thanks!
Thu Feb 25 18:01:45 -0800 2010
@Mikel,
I realized what I was doing wrong. Some code was returning before I could call mail in the method. It was then autorendering everything it could find.
This wasn’t obvious to me. I guess it makes sense given that Rails actions automatically render for you. Might be worth noting in the documentation some where that a call to mail isn’t actually needed to have the templates rendered.
I’m now trying to figure out how to return out of the message without going through the rendering. Is this possible? I’ve tried returning nil, etc. If I can’t then it sounds like any logic on whether to actually build the mail object should go outside/before the method?
Fri Mar 05 18:43:33 -0800 2010
Is there support for TLS ie gmail?
Mon Apr 26 18:13:52 -0700 2010
Very nice work. This should make things a lot easier and save a lot of time. Where can I get some documentation on this?
Tue Nov 08 19:56:09 -0800 2011
I love it! Following the conventions from controller with instance variables and format blocks feels so natural.
Sat Jun 12 23:52:40 -0700 2010
Very nice work Mike, I’d also like to know where to get a few pieces of documentation.
Thanks for all the help.
Fri Aug 06 03:54:07 -0700 2010
Hi,your blog is very nice and help me a lot,thanks
Fri Aug 06 03:55:30 -0700 2010
Hi,your blog is very nice and help me a lot,thanks
Mon Aug 23 18:17:20 -0700 2010
I’m having the same issue as Jack – I want to return from a method WITHOUT making/rendering an email (based on whether the users notification settings are set to send emails).
Any tips how to return without making a mail object? I’ve checked the code but some funny business is going around with the abstracted controller type…
Thu Nov 25 18:27:52 -0800 2010
hi,
Any idea for failure with exim ?
https://github.com/mikel/mail/issues#issue/70
the recipients is lost between rails app and exim.
Thu Nov 25 18:28:14 -0800 2010
hi,
Any idea for failure with exim ?
https://github.com/mikel/mail/issues#issue/70
the recipients is lost between rails app and exim.
Thu Nov 25 18:29:19 -0800 2010
oups sorry, after submit my comment, the form isn’t blanked.
Fri Nov 26 19:59:00 -0800 2010
Wow nice info, I have a question, what is alternative of
tmail = TMail::Mail.parse(email.mail)
at new API ?
Thanks
Sat Nov 27 00:00:16 -0800 2010
I think I figured out the code,
use Mail.new(email.mail)
Thanks :)
Wed Nov 09 04:57:07 -0800 2011
Veux simplement dire votre message est étonnante. La clarté dans votre contenu est tout simplement spectaculaire, et je peux supposer que vous êtes un expert sur ce sujet et bien sûr les nouvelles fonctionnalités sont vraiment génial, il va certainement aider à attraper le marché:). Eh bien avec votre permission me permettre de récupérer votre flux RSS à tenir à jour avec post à venir. Merci mille fois et s’il vous plaît suivre le travail gratifiant.
Wed Dec 15 02:21:38 -0800 2010
how it use ?
Tue Dec 06 09:22:13 -0800 2011
I have been visiting your blog for a while now and I always find a new posts. Thanks for sharing.
music production
Tue Dec 06 09:24:19 -0800 2011
I have been visiting your blog for a while now and I always find a new posts. Thanks for sharing.
music production
Tue Nov 15 10:50:33 -0800 2011
I really appreciate sharing this great post. Keep up your excellent work.
tekstovi pesama
dnevni horoskop
Tue Nov 15 10:50:43 -0800 2011
I really appreciate sharing this great post. Keep up your excellent work.
Sun Dec 11 00:57:51 -0800 2011
I sincerely got a kick from your article
Sun Dec 11 00:58:02 -0800 2011
I sincerely got a kick from your article
Thu Aug 04 01:37:30 -0700 2011
This piece became an inspiration for me to share with everyone I know. I must commend the writer and the site as well for coming up with a marvelous creation like this.
Mon Aug 08 01:13:27 -0700 2011
Your website id very nice , i like it very much , thank you for your sharing !
Fri Aug 19 21:38:19 -0700 2011
i love ur website…. keep it up
Fri Aug 19 21:41:16 -0700 2011
This blog post was absolutely fantastic. When I used to work in electroplating they sometimes encouraged us to write, but I could never come up with something as well written as that.
Tue Sep 06 23:52:01 -0700 2011
Very nice work. This should make things a lot easier and save a lot of time. Where can I get some documentation on this?
Thu Sep 15 04:10:41 -0700 2011
This blog is very educational and very well posted all valuable in order which I was looking forward from so many days.I value for your great efforts on relocation these information.
Sat Nov 26 19:36:12 -0800 2011
Great blog article about this topic,I have been lately in your blog once or twice now.I just wanted to say hi and show my thanks for the information provided.
4G LTE Phones
Wed Sep 21 17:10:53 -0700 2011
Thankyou online listings for your awesome insights, you have opened my eyes to the possibilities of the work that you do for us!
Sun Sep 25 18:22:53 -0700 2011
Thanks for the Action Mailer fix! I’ve been wanting to create an application for my ecommerce shopping cart that communicates with one of the fulfillment services companies that I have been told about. I really want an API that will allow the fulfillment software to communicate directly with my ecommerce software so that it automatically notifies them when I have an order. Is this something that can be done with my ecommerce site? Thanks!
Tue Oct 18 02:23:21 -0700 2011
Great blog article about this topic,I have been lately in your blog once or twice now.I just wanted to say hi and show my thanks for the information provided.
silver prices per ounce today
Tue Oct 18 02:23:37 -0700 2011
Great blog article about this topic,I have been lately in your blog once or twice now.I just wanted to say hi and show my thanks for the information provided.
silver prices per ounce today
Sun Oct 23 03:39:14 -0700 2011
Anybody catches this interest. It believes me like We’re the an individual who writes your content and never the blogger in the least. By plenty of time I’m just about finish looking through, I i’m expecting extra sentences to read simple things but them finds people out we am nearer to your end. We’re very a great deal excited to read simple things new article made by this page.
Sun Oct 23 03:40:52 -0700 2011
Anybody catches this interest. It believes me like We’re the an individual who writes your content and never the blogger in the least. By plenty of time I’m just about finish looking through, I i’m expecting extra sentences to read simple things but them finds people out we am nearer to your end. We’re very a great deal excited to read simple things new article made by this page.
Thu Oct 27 02:50:56 -0700 2011
New ActionMailer is the best of the best!
Thu Oct 27 02:51:37 -0700 2011
Hi! Great news! I’ve tried to fix Action Mailer problem many times but unfortunately without any results :(. But now it works! Thanks!
Wed Dec 21 20:57:27 -0800 2011
Anybody catches this interest. It believes me like We’re the an individual who writes your content and never the blogger in the least. By plenty of time I’m just about finish looking through, I i’m expecting extra sentences to read simple things but them finds people out we am nearer to your end. We’re very a great deal excited to read simple things new article made by this page.
Wed Dec 21 20:57:37 -0800 2011
Anybody catches this interest. It believes me like We’re the an individual who writes your content and never the blogger in the least. By plenty of time I’m just about finish looking through, I i’m expecting extra sentences to read simple things but them finds people out we am nearer to your end. We’re very a great deal excited to read simple things new article made by this page.
Thu Dec 22 18:40:56 -0800 2011
It’s not really an accurate model of the real world that a message knows how to deliver itself, although the postal system might be better off if zero-intelligence envelopes all delivered themselves (just a little smarter than the average postal worker!)lvaghubko sg tdeksuirr hg gwzfjrwfm te wufprcghm
Mon Dec 26 01:18:29 -0800 2011
I was very happy that I discovered this website. I needed to thank you for this excellent information!! I undoubtedly appreciated every bit of it and I have bookmarked your blog to check out the new stuff you post down the road.
Mon Dec 26 06:23:01 -0800 2011
I have both an html and text version of a template I’d like to use depending on a user’s preference. I thought I could pass a block to the mail call with some sort of logic but no matter what I do, it seems to always create a multipart email.
Tue Dec 27 03:00:59 -0800 2011
I really loved how you have created your site, it’s simple, neat, simple to get around and very easy on the eyes. Can you let me know which theme or designer did you use
Wed Dec 28 02:16:19 -0800 2011
I am very enjoyed for this blog. Its an informative topic.It help me very much to solve some problems. Its opportunity are so fantastic and working style so speedy.I think it may be help all of you.Thanks a lot for enjoying this beauty blog with me.
Thu Jan 05 01:36:49 -0800 2012
Good, that the old API still works. But bettering the efficience is important as always!
Kind regards
Fenster Andreas
Thu Jan 05 22:14:00 -0800 2012
Excellent stuff from you man. I’ve read your things before and you are just too awesome. I adore what you have got right here. You make it entertaining and you still manage to keep it smart. This is truly a great blog. Thanks for sharing.
chefs jackets
Thu Jan 05 22:14:21 -0800 2012
Excellent stuff from you man. I’ve read your things before and you are just too awesome. I adore what you have got right here. You make it entertaining and you still manage to keep it smart. This is truly a great blog. Thanks for sharing.
chefs jackets
Tue Jan 10 06:00:43 -0800 2012
I am having hard time merging this, could you share the guide.
Mon Jan 16 21:08:18 -0800 2012
Thanks for such a nice blog post….i was searching for something like that.
Tue Jan 17 00:28:10 -0800 2012
I needed to thank you for this excellent information!! I undoubtedly appreciated every bit of it and I have bookmarked your blog to check out the new stuff you post down the road.
Fri Jan 20 03:01:51 -0800 2012
GUCCI party packets will make you not lack confidence in themselves, and the small one integrated mass, became the most eye-catching fashion leading lady.
Fri Jan 20 23:49:24 -0800 2012
Excellent stuff from you man. I’ve read your things before and you are just too awesome.
Sat Jan 21 05:37:30 -0800 2012
Ruby Mail library, called, imaginatively enough, Mail very hard to use well, so I sat down and wrote a really
Mon Jan 23 00:28:55 -0800 2012
Thanks for the awesome article here. I am a huge fan of design so it is really interesting for me to read such stuff. I just hope to see more such nice articles.!
Tue Jan 24 04:21:42 -0800 2012
Excellent stuff from you man. I’ve read your things before and you are just too awesome. I adore what you have got right here. You make it entertaining and you still manage to keep it smart. This is truly a great blog. Thanks for sharing.
Sun Jan 29 20:49:37 -0800 2012
Very good post. I realize that I was totally wrong about this issue. I guess you learn something new every day. Lesson learned Ms. Right! Nice website, informative on the road.
Wed Feb 01 14:05:16 -0800 2012
Exactly what I was looking for. Just don’t tell my boss all my knowledge of rails comes from the internet.
Wed Feb 01 18:18:37 -0800 2012
This is still just as disgustingly abhorrent as an Atari 2600 iPod dock. Seriously. Why would someone ruin the best game system of all time by making it into a PC?
Thu Feb 02 09:22:42 -0800 2012
very gooood thanks a lot!!