Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

ActionMailer Mailer Views and Content Type

#2338

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

content_type "text/html"

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?

Thanks

Reported by Vidal Graupera · March 25th, 2009 @ 01:19 PM

State: duplicate
Milestone: 2.3.6
Assigned to: Michael Koziarski Michael Koziarski
Importance: Low

Activity

  1. thedarkone
    thedarkone

    Hi Vidal,

    is this still a problem on master (past v2.3.2.1 tag)?

    March 25th, 2009 @ 04:28 PM

  2. Blake Carlson
    Blake Carlson

    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 v2.3.2.1 tag.

    If I can get a repro, I'll update here and/or file a new ticket.

    • Blake

    March 26th, 2009 @ 12:59 AM

  3. Joshua Krall
    Joshua Krall

    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.

    April 19th, 2009 @ 01:44 AM

  4. Joshua Krall
    Joshua Krall

    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)

    April 19th, 2009 @ 04:40 AM

  5. Joshua Krall
    Joshua Krall

    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.

    April 19th, 2009 @ 08:20 AM

  6. Joshua Krall
    Joshua Krall
    • 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:

    
    layouts/auto_layout_mailer.html.erb
    layouts/auto_layout_mailer.text.erb
    

    And I changed them to:

    
    layouts/auto_layout_mailer.text.html.erb
    layouts/auto_layout_mailer.text.plain.erb
    

    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 :-)

    April 19th, 2009 @ 11:23 AM

  7. Justin Weiss
    Justin Weiss

    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.

    May 13th, 2009 @ 10:14 PM

  8. thedarkone
    thedarkone

    Justin, I posted a similar patch in #2263 more than a month ago. Good luck :).

    May 14th, 2009 @ 08:11 AM

  9. Tom
    Tom

    I am so glad I found this! I thought I was losing my mind! I am having the exact same problem, but ONLY when the emails are generated from Workling on my production server. The HTML template is used to populate a single-part plain text email.

    May 20th, 2009 @ 11:28 PM

  10. gobigdave
    gobigdave

    Justin, thanks for the patch. It solved my problem where emails didn't work right when sent from Workling.

    The question now is whether this will make it into Rails 2.3.3.

    May 21st, 2009 @ 05:57 PM

  11. Fernando Guillen
    Fernando Guillen
    • 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:

    http://github.com/fguillen/ActionMailerTest

    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.

    July 31st, 2009 @ 10:08 AM

  12. Michael Koziarski
    Michael Koziarski
    • Assigned user set to Michael Koziarski
    • Milestone changed from 2.x to 2.3.4

    August 3rd, 2009 @ 05:59 AM

  13. iGEL
    iGEL

    Justin's patch does solves the problem. But shouldn't be .to_s return the same result as to_str? Sounds like a source for future bugs to me.

    August 7th, 2009 @ 03:52 PM

  14. Jérôme
    Jérôme

    Experiencing the same bug in 2.3.2, but it only happens sometimes, a situation making me mad since I send over 200.000 emailings a week and I sometimes have to restart the rails application to make the template detection work !!

    September 5th, 2009 @ 02:11 PM

  15. Jeremy Kemper
    Jeremy Kemper
    • Milestone changed from 2.3.4 to 2.3.6

    [milestone:id#50064 bulk edit command]

    September 11th, 2009 @ 11:04 PM

  16. Brendon
    Brendon

    I've had this problem for quite some time now. Thanks everyone for putting in the work to figure it all out. I hope it gets stomped out for 2.3.5. Seems like such a huge bug, I'm not sure how there couldn't have been tests for it :)

    September 15th, 2009 @ 09:34 AM

  17. Brendon
    Brendon

    Just thought I'd add, I tried the patch above and HTML emails still get sent as plaintext.

    September 15th, 2009 @ 09:51 AM

  18. Vidal Graupera
    Vidal Graupera

    FYI, I upgraded to 2.3.5 and these problem persist. Please fix in 2.3.6 as this has been open a long time. Thanks.

    December 8th, 2009 @ 06:26 AM

  19. Brendon
    Brendon

    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 :)

    January 13th, 2010 @ 03:45 AM

  20. tsailipu
    tsailipu
    • 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.

    January 13th, 2010 @ 06:44 AM

  21. José Valim
    José Valim

    Guys, we have two patches, but we cannot ensure that the problem won't come back again, because they don't have tests. If someone attach a patch with tests, I will apply it and try to solve the problem ASAP.

    January 13th, 2010 @ 08:03 AM

  22. José Valim
    José Valim
    • State changed from new to duplicate

    Duplicate of #2263.

    March 19th, 2010 @ 11:55 PM

  23. Zack Hubert
    Zack Hubert
    • Importance changed from to Low

    We're in the process of evaluating 2.3.8 (still on 2.3.2 in production) and Joshua's monkeypatch for default_template_format is still needed to properly send implicit multi-part emails.

    This doesn't appear to be resolved.

    July 1st, 2010 @ 07:48 PM

  24. subimage
    subimage

    I'm on 2.3.8 and still experiencing this. Why hasn't this been patched yet in trunk? Super annoying.

    September 12th, 2010 @ 01:11 AM

  25. Andrea Campi
    Andrea Campi
    • Tag changed from 2, actionmailer, layout, multipart to 2-3-stable, actionmailer, layout, multipart

    October 16th, 2010 @ 11:37 PM

  26. jnimety
    jnimety

    I've been able to reproduce this bug on 2.3.10, using delayed_job to deliver a multipart email.

    1. start delayed_job from Rails.root
    2. schedule an email delivery via delayed job. wait for delayed_job to process and verify that the email is delivered as multipart/alternative
    3. move/rename your Rails.root directory
    4. 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?

    October 21st, 2010 @ 08:08 PM

  27. jnimety
    jnimety

    I forgot to mention that we use Capistrano for deployment on production. I believe when Capistrano recreates symlinks to point to the current release that it is causing a situation similar to my above steps.

    October 21st, 2010 @ 08:56 PM