Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attachment shows as text in body of email #25

Open
OpenCoderX opened this issue Sep 3, 2014 · 11 comments
Open

Attachment shows as text in body of email #25

OpenCoderX opened this issue Sep 3, 2014 · 11 comments
Labels

Comments

@OpenCoderX
Copy link
Member

This is the email body:

Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;
 charset=UTF-8
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
 filename="Daily Status 2014-09-02.xlsx"
Content-ID: <[email protected]>

UEsDBBQAAAgIAACYn+tjOGvU2QAAAEECAAALAAAAX3JlbHMvLnJlbHOtksFO
wzAMhu88ReT7mm5ICKFluyCk3RAqD2ASt43axJEToLw9gQNiaAgOO1r2//3f
wdv9Emb1QpI9RwPrpgVF0bLzcTDw2N2trmG/2z7QjKVe5NGnrGokZgNjKelG
62xHCpgbThTrpmcJWOoog05oJxxIb9r2Sst3BhwzVYcyUDGwzPqVZXpinpoK
A9W9JfpPFfe9t3TL9jlQLCcaf1yAOjgDcnBr0L+4OLb3wjVpWejcNoEKOiz4
CV+l2kNSPOUvr83fXpjSubVoKRQduVNGlx9G+ugVdhfvUEsDBBQAAAgIAACY
n+vvyqPEyAEAAAkFAAANAAAAeGwvc3R5bGVzLnhtbKVU22rcMBB971cIfUBl....

This is my mailer:

class StatusMailer < ActionMailer::Base
    default to: Proc.new { ['[email protected]']}, from: "[email protected]"

    def daily_coding_status

        # execute sp
        status_results = DailyStatus.execute_procedure("get_coding_status")

        # cache date
        @date = Time.zone.today.to_s

        xlsx = render_to_string handlers: [:axlsx], formats: [:xlsx], template: "status_mailer/status", locals: { status_results: status_results }
        attachments["Daily Status #{@date}" + ".xlsx"] = { mime_type: Mime::XLSX, content: xlsx}
        mail(:subject => "#{@date}  Status Report")
    end
end

This is the template 'status.xlsx.axlsx':

# build excel file
wbook = xlsx_package.workbook
wbook.add_worksheet(:name => "Daily Status") do |sheet|
    sheet.add_row ["Parent Location RID", "Location RID", "Location Name", "Unique Tools", "Total Parts", "Total Coded", "Total Not Coded", "Total Questions", "Total Do Not Code",
          "Total Ready To Code", "Unique Parts", "Unique Coded", "Unique Not Coded", "Unique Questions", "Unique Do Not Code", "Unique Ready To Code", "Percent Coded",
          "1 Day Difference", "7 Day Difference", "30 Day Difference"]

    status_results.each do |result|

    data_row = [result['parent_location_rid'], result['location_rid'], result['location_name'], result['unique_tools'], result['total_parts'], result['total_coded'], result['total_not_coded'],
                result['total_questions'], result['total_do_not_code'], result['total_ready_to_code'], result['unique_parts'], result['unique_coded'], result['unique_not_coded'], result['unique_questions'],
                result['unique_do_not_code'], result['unique_ready_to_code'], result['percent_coded'], result['one_day_difference'], result['seven_day_difference'], result['thirty_day_difference']]

      #add the row to the sheet
      sheet.add_row data_row, :types => [:string, :string, :string, :string, :string, :string, :string, :string, :string, :string, :string, :string, :string, :string, :string, :string, :string, :string, :string, :string]
    end
end

I can't see what I'm doing incorrectly.

@straydogstudio
Copy link
Collaborator

Do you have any text in the body of your message? E.g. do you have a template for daily_coding_status? Perhaps it is confused at having no content.

What rails are you using?

@OpenCoderX
Copy link
Member Author

Rails 3.2. That was indeed the solution. Once I added html and text templates and a proper do format block in my call to mail(), it worked.

Thanks

@deXterbed
Copy link

@chrisgogreen ran into the same issue and i did have an html template for my mailer. I used this workaround:

xlsx = render_to_string handlers: [:axlsx], formats: [:xlsx], template: "releases/order_report"
attachments["DailyOrderReport.xlsx"] = {mime_type: Mime::XLSX, content: xlsx}
self.instance_variable_set(:@_lookup_context, nil)
mail(to: recipients, subject: "Daily Order Report")

@straydogstudio
Copy link
Collaborator

@ph0t0n Which Rails version?

@OpenCoderX
Copy link
Member Author

@ph0t0n I think you need to pass a block to mail()like this:

mail(:subject => "#{@Date} Status Report") do |format|
format.html { render 'template_name' }
format.text { render :text => 'template_name.txt.erb' }
end

Why don't you need a template? You could use an empty template, instance_variable_set smells fishy.

@straydogstudio
Copy link
Collaborator

@ph0t0n @chrisgogreen According to the ActionMailer documentation the block isn't required. So I'd like to isolate what is going on either way.

I agree, I don't like having to reset the lookup context. It shouldn't be necessary. Recently Rails has started caching certain aspects of the rendering process to make things more efficient. I would not be surprised if it is related.

@ph0t0n What Rails are you running?

@OpenCoderX
Copy link
Member Author

My complete version number is 3.2.19. Let me know what else I can check for you.

@OpenCoderX OpenCoderX reopened this Sep 11, 2014
@SimonBo
Copy link

SimonBo commented Jul 6, 2016

Same thing happening on 3.2.18. Adding self.instance_variable_set(:@_lookup_context, nil)
fixes the problem.

@Roko131
Copy link

Roko131 commented Jan 3, 2017

Same on ruby 2.1.7, rails 3.2.12.
Adding self.instance_variable_set(:@_lookup_context, nil) fixes the problem.

Another solution?
Instead self.instance_variable_set(:@_lookup_context, nil) I could do use render_to_string again, this time just to force the html format, adding formats: [:html] , notice I don't actually use the return value though its result will be (somehow?) used as the mail content.

render_to_string(formats: [:html], :action => "path/to/action", :layout => false)
mail(subject: "Test", to: email)

The mail content will be taken from the render_to_string result,
For empty email:
render_to_string(formats: [:html], text: nil, :layout => false)
Or if you want the default action path, you can remove the action option:
render_to_string(formats: [:html], :layout => false)
I use this, without even the layout option (since I didn't define layout?)
render_to_string(formats: [:html])

@straydogstudio
Copy link
Collaborator

@Roko131 Thanks for this result. That makes sense now why the first call to render to string is showing up in the message if your second render to string is producing the message. I'll have to dig into the lookup context to see what is going on sometime.

@vaibhav8186
Copy link

Mail is going but in attachment, a sheet is not opening.
Screenshot from 2019-07-26 14-18-38

My rails version: 4.2
Ruby Version: 2.2.4

My mailer action:
def send_timesheet_summary_report(project_employee, projects_summary, employee_summary)
data_file = render_to_string(
layout: false, handlers: [:axlsx], formats: [:xlsx],
template: 'time_sheets/export_project_report',
locals: { project_employee: project_employee, projects_summary: projects_summary, employee_summary: employee_summary }
)
attachment = Base64.encode64(data_file)
attachments["Timesheet_summary_report.xlsx"] = {mime_type: Mime[:xlsx], content: attachment, encoding: 'base64'}
self.instance_variable_set(:@_lookup_context, nil)
mail(
subject: "Timesheet summary report",
to: "[email protected]")
end

and my action name and template name is different

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants