This project is archived and is in readonly mode.
ActionMailer Mailer Views and Content Type
I upgraded from Rails 2.2 to 2.3.2.
I have mailer views, e.g. message.text.html.erb and message.text.plain.erb. Before, this use to automatically pick up both and set the content type correctly per the documentation at http://guides.rubyonrails.org/ac...>
Now, it is rendering the HTML .text.html.erb but setting Content-Type: text/plain. This results in emails that show all the html markup in the display.
To get this to work now, I have to set
in the methods in my UserMailer class. Did not need to do this before.
Did something change between previous versions of rails and 2.3, or is this broken in 2.3?
Comments and changes to this ticket
I'll just chime in and mention that I've been fighting some issues with implicit multipart email, layouts, and content type. I'm seeing the *.text.html.erb layout being used for the "text/plain" part. Issue seems to be around ActionView::PathSet#find_template returning the wrong template when called for format :text.
Strangely, the problem only occurs in a staging environment -- everything works as expected in my dev environment.
I'm using v220.127.116.11 tag.
If I can get a repro, I'll update here and/or file a new ticket.
I'm also seeing this problem... and also strangely only in our production environment.
Even weirder is this: In our production environemnt, the mailer is creating proper multipart emails when I trigger them using a rake task, but when they are fired off by our background workling process... I get the text/plain problem.
Still trying to diagnose.
Update: I can get my emails to use the text/html content-type, by ensuring that my emailing process runs with the current directory set to RAILS_ROOT.
Now... however, I'm seeing the same problem as Blake. My emails are coming through with 2 parts: my HTML layout as text/html, and my HTML layout as text/plain.
(...despite having a .text.plain.erb layout in /layouts)
OK... I tracked this down for me at least. Unfortunately, I don't have time to check out rails, run the tests, and submit a proper patch.
To get this working for me... I modified ActionMailer::Base#default_template_format as follows:
def default_template_format if @current_template_content_type @current_template_content_type.sub('/','.') # Mime::Type.lookup(@current_template_content_type).to_sym else :html end end
As best I can tell, the problem is that the Mime::Type.lookup returns :text for "text/plain". Unfortunately, the template loading code maps paths such as:
layouts/my_mailer.text.html.erb layouts/my_mailer.text.html layouts/my_mailer.text layouts/my_mailer.html
for template.paths like: layouts/my_mailer.text.html.erb
So, the my_mailer.text mapping is created for :html as well as :text. When the Mime::Type method is used, the :text symbol is not sufficient to distinguish the text.plain template from text.html.
I'm not sure what the purpose of Mime::Type.lookup is... but my fix seems to work for me anyway.
- Tag set to 2-3-stable, actionmailer, layout, multipart
OK... here's a patch. It should apply on top of the 2-3-stable branch.
Note: All mailer tests pass, but in order to do so, I had to change the "autolayout" layouts so that they were named according to the docs here: http://guides.rubyonrails.org/ac...
They were named like this:
And I changed them to:
I'm not sure what implication this has for backwards compatibility... so this is up for discussion. But, it seems more consistent to me, and it has the bonus feature of conforming to the official rails docs :-)
Looks like this is because ActionMailer::Base uses #template_path to build the list of templates to render. This interpolates an ActionView::Template::Path, which calls #to_s, which turns the path relative (instead of absolute) if RAILS_ROOT is defined. If you're like us and have mailer jobs run from cron, this relative path probably doesn't mean much to Dir.glob, and ActionMailer can't find its templates.
The attached patch changes template_path to use Path#to_str instead of #to_s, which fixed our problem by making template_path return an absolute path.
- Tag changed from 2-3-stable, actionmailer, layout, multipart to 2-3-3, actionmailer, layout, multipart
On a Rails 2.3.3 ActionMailer test application I have the same problem if I try to run the test not on the RAILS_ROOT dir, but works if I run the test from the RAILS_ROOT dir:
ActionMailerTest $ ruby test/unit/mailer_test.rb -n test_wadus_mail Loaded suite test/unit/mailer_test Started . Finished in 0.16397 seconds. 1 tests, 2 assertions, 0 failures, 0 errors ActionMailerTest $ cd test/unit/ ActionMailerTest/test/unit $ ruby mailer_test.rb -n test_wadus_mail Loaded suite mailer_test Started F Finished in 0.445245 seconds. 1) Failure: test_wadus_mail(MailerTest) [mailer_test.rb:6]: <"multipart/alternative"> expected but was <"text/plain">. 1 tests, 1 assertions, 1 failures, 0 errors
I think this is because the test fails when I try to run it with Texmate Ctrl+R bundle.
I agree, this bug has been around for a long time. And I would think it'd affect a whole lot of people? I've been holding off deploying until a fix arrives but have given up. Just in case anyone wants to get their setup going again, it's actually pretty easy to just explicitly declare the different templates like so:
content_type "multipart/alternative" part "text/plain" do |p| p.body = render_message("invoice.text.plain", :order => order) end part :content_type => "text/html", :body => render_message("invoice.text.html", :order => order)
So instead of having your body hash as an option, you just pass that hash into each of the render_message functions. Make sure you put the HTML one last if you want to show that one by default in an email client.
By the way, I appreciate all the hard work the team members are putting to Rails 3 and know that that is their number one priority :)
- Tag changed from 2-3-3, actionmailer, layout, multipart to 2, actionmailer, layout, multipart
Yike, just now found out about this bug, too (upgraded from 2.1.x to 2.3.5 a while ago but only now a user emailed me about it). Quite unfortunate to have to experience and see this (perhaps regression tests, or lack thereof, on this failed?). When people ask me these days what I dislike about RoR, this inconsistency/breakage across versions without warning (i.e. not mentioned at all in the release note) is a main one. Thanks for fixing. But hope that the community can help better the practice of not breaking or at least warn developers about inconsistency/difference in design/assumption in the version release note if the breakage/inconsistency is intentional.
I've been able to reproduce this bug on 2.3.10, using delayed_job to deliver a multipart email.
- start delayed_job from Rails.root
- schedule an email delivery via delayed job. wait for delayed_job to process and verify that the email is delivered as multipart/alternative
- move/rename your Rails.root directory
- schedule an email delivery via delayed job. wait for delayed_job to process. When testing in development I receive a template missing error, when testing in production the email is delivered as text/plain, using the html template as the body.
I'm guessing that the email is still delivered in production because the multipart templates are cached. However, the code that determines the mimetype looks for files on disk, doesn't find anything, and defaults to text/plain. I don't know enough about ActionMailer internals to know if this is a correct assessment. Should create! check the cache when searching for templates to add to @parts?
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
Tickets have moved to Github
The new ticket tracker is available at https://github.com/rails/rails/issues