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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With