Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trouble adding a file stored on S3 through Paperclip as an attachment in ActionMailer

I'm using Paperclip and S3 for file upload and storage in a Rails 3 app. The uploading of the files is working well, but when trying to attach an uploaded file to an email message with actionmailer, I am running into issues. After a lot of troubleshooting, hopefully someone can offer a hint.

From a high level, it seems like I may need to download the file first, with some kind of download method before attaching, which is suggested here but I do not quite follow on how to implement - paperclip + ActionMailer - Adding an attachment?

In the app, after a user uploads a file (a Quiz in this case), the admin should be notified via email with the file that was uploaded by the user. I keep running into a "No such file or directory". Below is the code I am working with right now. Any ideas or suggestions would be much appreciated!

Quiz.rb model - what users are uploading:

class Quiz < ActiveRecord::Base
attr_accessible :quiz_path, :user_id, :tutorial_id

validates_presence_of :quiz_path
validates_attachment_size :quiz_path, :less_than => 50.kilobytes    
validates_attachment_presence :quiz_path 
validates_attachment_content_type :quiz_path, 
  :content_type => ["application/pdf","application/vnd.ms-excel",     
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"],
  :message => 'We only accept Microsoft Excel files ending in .xlsx or .xls'

belongs_to :user
belongs_to :tutorial
has_attached_file :quiz_path,
:storage => :s3,
:s3_permissions => :private,
:path => "quizzes/:attachment/:style/:id.:extension",
:storage => :s3,
:s3_credentials => {
  :access_key_id => ENV["AWS_ACCESS_KEY_ID"],
  :bucket => ENV["S3_BUCKET_NAME"],
  :secret_access_key => ENV["AWS_SECRET_ACCESS_KEY"]
}

end

The AdminMailer class:

 class AdminMailer < ActionMailer::Base

  default from: "[email protected]"

  def admin_upload_notification_email(quiz, current_user)
  @url  = "http://mydomain.com"
  @quiz = quiz
  @user = current_user
  mail(to: "[email protected]", :subject => "New Upload From #{@user.email}")
  attachments["#{quiz.quiz_path_file_name}"] = File.read("{quiz.quiz_path.expiring_url(60)}")
  end
 end

Also adding the QuizzesController:

def create
 @user = current_user
 @quiz = @user.quizzes.create(params[:quiz])

 respond_to do |format|
  if @quiz.save
    UserMailer.upload_notification_email(@user).deliver
    AdminMailer.admin_upload_notification_email(@quiz, @user).deliver

    format.html { redirect_to @user, notice: 'Your skill assessment answer file was successfully uploaded.  We will review your responses and email you a link to your results as soon as possible.' }
    format.json { render json: @user, status: :created, location: @quiz }
  elsif @quiz.errors.any?
    flash[:error] = 'Please make sure you selected your answer file and it ended in ".xlsx".'
    return(redirect_to :back)
  else  
    format.html { redirect_to @user, notice: 'No file was selected.  Please back and choose "Select Your Answer File" before submitting.' }
    format.json { render json: @quiz.errors, status: :unprocessable_entity }
  end
 end
end
like image 499
pvskisteak5 Avatar asked Mar 18 '13 04:03

pvskisteak5


1 Answers

After messing around some more, was able to get it working. Below is what worked for me - hopefully it helps someone. The key was using open uri since the quiz files are on S3.

class AdminMailer < ActionMailer::Base

require 'open-uri'

default from: "[email protected]"

def admin_upload_notification_email(quiz, current_user)
  @url  = "http://mydomain.com"
  @quiz = quiz
  @user = current_user
  attachments["#{quiz.quiz_path_file_name}"] = open("#{quiz.quiz_path.expiring_url(60)}").read

  mail(to: "[email protected]", :subject => "New Upload From #{@user.email}")
end


end
like image 51
pvskisteak5 Avatar answered Sep 20 '22 03:09

pvskisteak5