How can I attach multiple files to an ActionMailer mail object? (Without it attaching several unwanted text files as well.)
Asked Answered
V

2

7

I am successfully generating and sending an email with the following code.

class UserMailer < ActionMailer::Base
  default :from => '[email protected]',
          :date => Time.now

  def new_user(user)
    mail_subject = ['WELCOME TO ACME, INC', 'USER ACTIVATION']
    @user = user

    mail.attachments['File One.pdf'] = File.read(File.join(ATTACHMENT_DIR, 'shared', 'file_one.pdf'))
    mail.attachments['File Two.pdf'] = File.read(File.join(ATTACHMENT_DIR, 'shared', 'file_two.pdf'))
    mail.attachments['File Three.pdf'] = File.read(File.join(ATTACHMENT_DIR, 'shared', 'file_three.pdf'))
    mail.attachments['File Four.pdf'] = File.read(File.join(ATTACHMENT_DIR, 'shared', 'file_four'))

    mail( :to      => user.address.email,
          :subject => mail_subject.join(' ~ ').upcase )

  end
end

However, the email contains three text documents which are identical to the content of the email body. The view I'm using for the mailer is named new_user.text.erb.

I suspect that for each pdf document I'm attaching, a plain text document is generated as well, the first being the actual email document body and the remaining three are attached along with the pdf documents.

How may I attach these pdf documents without also attaching these (repeating) text documents? Has anyone else run into this?

Vulgarian answered 20/4, 2011 at 22:31 Comment(5)
+1. I'm running into this also.Dilative
If you add the mime type and content like in the guide, does it fix the problem?Corrody
I believe I had explicitly added the mime type and found no differences. But it's been a while since I was working on this feature and so it's not fresh in my brain, will need to re-visit this.Vulgarian
Appears to be a bug. The email template is rendered and added to the mail object for each attachment that is added. Testing with text and html templates, adding 3 attachments gives me 4 html rendered mail parts and 2 plain text rendered mail parts. Is the extra parts that are added causing trouble when viewing the mail or do you want to remove them just for DRY's sake?Corrody
The extra attachments would serve to cause confusion on the recipient's part. Currently I have one zipped file attached because I wasn't making any progress in preventing multiple email body text attachments. And the zipped file confuses the recipients, which I suspected would happen.Vulgarian
H
5

Try to use attachments['..'] instead of mail.attachments['..], it works here this way, and no duplicates are observed.

I'm on Rails 3.0.7, mail 2.2.19:

The only other difference that I see, is that I've a hash with mime_type and content. But I think that it worked the other way as well, it just was assigning a mime-type which was not adequate.

attachments['event.ics'] = {:mime_type=>'text/calendar', :content => ics}

mail({
  :to => email,
  :subject => subject,
}) do |format|
  format.text { render :inline => mail_template }
  ...
end
Haftarah answered 5/5, 2011 at 21:23 Comment(16)
On what version of Ruby and Rails does it work for you? It does not work for me on Ruby 1.8.7 and Rails 3.0.7.Corrody
1.9.2 and 3.0.7. I'll paste it a bit later. What do you mean "doesn't" work? What version of mail gem are you using, check Gemfile.lockHaftarah
Looking forward to testing this later as time permits.Vulgarian
No duplicates with Rails 3.0.6.rc1 on 1.8.7, when using attachments[]. There are duplicates when using mail.attachments[]. Maybe I messed up something when testing this earlier.Corrody
I changed mail.attachments[] to attachments[] and this did not solve my woes. Using this syntax I'm unable to attach more than one file. My ActionMailer gem is 3.0.4. I'm stumped and I have to say I was pretty excited to see this work.Vulgarian
@Tass: not actionmailer, but, rather "mail" gem. gem list mailHaftarah
I had just realized that's what you were after. It's 2.2.15.Vulgarian
What happens when you add several attachments using attachments['filename.ext'] approach? It works here..Haftarah
@Roman, I did try that. When I changed the syntax to attachments['filename.ext'] it did not deliver the email. I then tried using that syntax and attaching a singular file, then the email was delivered. However, I was also able to successfully deliver an email originally with only one attachment. No joy here. In summary, changing my syntax to attachments['filename.ext'] did not work. My issue is not resolved but looks like you'll get the bounty since you have more than two upvotes. Hmph.Vulgarian
What does it do? Try to change the delivery method, and check the tmp/mails for contents (config.action_mailer.delivery_method = :test)Haftarah
@Zabba, are you still not having any luck either? I'll need to set aside some time to take a look at this eventually just out of sheer curiosity. I've since moved on, we've decided to mail a .zip file. @Roman, thanks for your help. Hope to be able to report back soon.Vulgarian
@Tass: I'm curious too. Keep me posted.Haftarah
@Tass, I did have success as I mentioned in an earlier comment.. it is working fine (no duplicates) when I use attachments[] (and not mail.attachments[]). This is in Rails 3.0.6.rc1 and Ruby 1.8.7.Corrody
Perhaps I should try it in Ruby 1.8.7, why else would I use RVM? ;-) And I should pay closer attention to what I'm reading, I did see that you reported successful results, @Zabba.Vulgarian
@Tass: did you upgrade the mail gem? This is the most important part of the puzzle!Haftarah
@Roman: I haven't. I'm going to try using 1.8.7 first since it's an easy switch with RVM. I'm also able to use another gem file as well, aren't I? With mail 2.2.19?Vulgarian
D
2

I'm on Rails version 5.2.4.5. Hope it will help:

My reference comes from here 2.3.1 Adding Attachments and Attachments.

If you want to attach multiple files.

Just call this Method repeatedly. And it will send the mail with two file.

attachments["YourFile.csv"] = {mime_type: 'text/csv', content: csv_data}
attachments["YourFile2.csv"] = {mime_type: 'text/csv', content: csv_data}

This is my example that generate CSV and PDF and mail them in same time for your reference:

    headers = ['Name', 'Age', 'Party', 'Vote']
    csv_data = CSV.generate(headers: true) do |csv|
        csv << headers
        @candidates.each do |people|
            csv << [people.name, people.age, people.party, people.vote_logs_count]
        end
    end
    attachments["Report.csv"] = {mime_type: 'text/csv', content: csv_data}
    attachments["Report2.pdf"] = WickedPdf.new.pdf_from_string(
        render_to_string(:pdf => "pdf",:template => 'candidates/pdf.html.erb')
      )
    mail(
        from: "SomeOne" + "@SomeHashDomain.mailgun.org",
        to: '[email protected]', 
        subject: "CSV and PDF report"
    )

Supplementary note: I use WickedPdf Gem to generate PDF.

Diversification answered 23/3, 2021 at 3:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.