ActionMailer is a weird, fussy black box whose intricacies produce a lot of code duplication, especially for dealing with multi-language email, where you need to use a different .erb file for each language. Here’s an example of how you can reduce some of that duplication.
Code speaks louder than words so I’ll just cut and paste – you can see pretty easily what I’ve done. Works, although it’s completely undocumented and is probably not very good practise.
Previous, highly redundant code. I’ve snipped this a lot – you don’t have to use much imagination to see why I don’t like this:
def tokenmail_eng(user, subject) subject subject body :token => user.password_hash, :password => user.password, :user_id => user.id, :name => user.nickname recipients user.email_address_with_name from '' sent_on Time.now headers "Reply-to" => "" end def tokenmail_jpn(user, subject) subject subject body :token => user.password_hash, :password => user.password, :user_id => user.id, :name => user.nickname recipients user.email_address_with_name from '' sent_on Time.now headers "Reply-to" => "" end def tokenmail_zhs(user, subject) subject subject body :token => user.password_hash, :password => user.password, :user_id => user.id, :name => user.nickname recipients user.email_address_with_name from '' sent_on Time.now headers "Reply-to" => "" end
Woah. That is *awful*. When I finally decided to clean up my mail code I found several problems even in my cut and pasted code – when you do that a few times, and then go in to make a change, you are almost guaranteed to leave something out. That is precisely why cut and pasting code is something you should never, ever do.
So how do we clean this up and merge into a “generic” mail, while fooling ActionMailer into using the correct file?
Turns out we can do this:
def tokenmail_gen(user, subject) subject subject body :token => user.password_hash, :password => user.password, :user_id => user.id, :name => user.nickname recipients user.email_address_with_name from '' sent_on Time.now headers "Reply-to" => "" end def tokenmail_eng(user, subject) tokenmail_gen(user, subject) end def tokenmail_jpn(user, subject) tokenmail_gen(user, subject) end def tokenmail_zhs(user, subject) tokenmail_gen(user, subject) end def tokenmail_zht(user, subject) tokenmail_gen(user, subject) end
That’s so much better it brings a tear to my eye. Needless to say you will need to handle translation of the subjectline in your Controller.
SERIOUS NOTE: This is undocumented and while it seems to work, I haven’t heard of anyone else doing it and it might not work in future. Use at your own risk and make sure your tests cover it!