Heroku ha un timeout di 30 secondi su qualsiasi richiesta del server (appresa nel modo più duro), quindi è assolutamente necessario archiviare i file su s3.
Prova carrierwave (carrierwave railscasts) invece di graffetta, come io preferisco gli assistenti aggiunti che arrivano a bordo, in più c'è un certo numero di grandi plugin, come carrierwave_direct per il caricamento di file di grandi dimensioni a S3, che si integrano perfettamente con carrierwave.
Delayed_job (railscast - delayed_job) funzionerà correttamente per l'eliminazione di file da s3 e qualsiasi altra elaborazione in background che potrebbe essere richiesta.
Il mio file gioiello include i seguenti:
gem 'delayed_job'
gem "aws-s3", :require => 'aws/s3'
gem 'fog'
gem 'carrierwave'
gem 'carrierwave_direct'
nebbia gemma è un bel modo per avere tutti i vostri account di informazioni in un unico luogo e imposta a tutto abbastanza bene. Per la gemma AWS how-to, buona risorsa.
Ecco un controller di esempio al momento della presentazione di un modulo da caricare (ci sono sicuramente migliori modi di fare questo, ma a scopo illustrativo)
def create
@asset = Asset.new(:description => params[:description], :user_id => session[:id], :question_id => @question.id)
if @asset.save && @asset.update_attributes(:file_name => sanitize_filename(params[:uploadfile].original_filename, @asset.id))
AWS::S3::S3Object.store(sanitize_filename(params[:uploadfile].original_filename, @asset.id), params[:uploadfile].read, 'bucket_name', :access => :private, :content_type => params[:uploadfile].content_type)
if object.content_length.to_i < @question.emailatt.to_i.megabytes && object.content_length.to_i < 5.megabytes
url = AWS::S3::S3Object.url_for(sanitize_filename(params[:uploadfile].original_filename, @asset.id), 'bucket_name')
if @asset.update_attributes(:download_link => 1)
if Usermailer.delay({:run_at => 5.minutes.from_now}).attachment_user_mailer_download_notification(@asset, @question)
process_attachment_user_mailer_download(params[:uploadfile], @asset.id, 24.hours.from_now, @question.id)
flash[:notice] = "Thank you for the upload, we will notify this posts author"
end
end
end
else
@asset.destroy
flash[:notice] = "There was an error in processing your upload, please try again"
redirect_to(:controller => "questions", :action => "show", :id => @question.id)
end
end
private
def sanitize_filename(file_name, id)
just_filename = File.basename(file_name)
just_filename.sub(/[^\w\.\-]/,'_')
new_id = id.to_s
new_filename = "#{new_id}" + just_filename
end
def delete_process(uploadfile, asset_id, time, question_id)
asset = Asset.find(:first, :conditions => ["id = ?", asset_id])
if delete_file(uploadfile, asset_id, time) && asset.destroy
redirect_to(:controller => "questions", :action => "show", :id => question_id)
end
end
def process_attachment_user_mailer_download(uploadfile, asset_id, time, question_id)
asset = Asset.find(:first, :conditions => ["id = ?", asset_id])
if delete_file(uploadfile, asset_id, time) && @asset.delay({:run_at => time}).update_attributes(:download_link => 0)
redirect_to(:controller => "questions", :action => "show", :id => question_id)
end
end
#S3 METHODS FOR CREATE ACTION
#deletes the uploaded file from s3
def delete_file(uploadfile, asset_id, time)
AWS::S3::S3Object.delay({:run_at => time}).delete(sanitize_filename(uploadfile.original_filename, asset_id), 'bucket_name')
end
Un sacco di codice non necessario, lo so (scritto questo quando ho stava iniziando con Rails). Speriamo che possa dare un'idea dei processi coinvolti nello scrivere questo tipo di app. Spero che sia d'aiuto.