Christopher Spears
Christopher Spears

Reputation: 1105

Downloading a sound file from AWS using Paperclip

I am working on a Ruby on Rails 4 project that has been deployed to Heroku. Basically, a user needs to have the ability to upload and download sound files. Uploading a file was fairly straight forward. However, downloading has been strangely difficult. I have found several posts on Stack Overflow that have been helpful, but I still need help.

In config/environments/production.rb:

config.paperclip_defaults = {
    :storage => :s3,
    :s3_protocol => 'http',
    :s3_credentials => {
      :bucket => ENV['S3_BUCKET_NAME'],
      :access_key_id => ENV['AWS_ACCESS_KEY_ID'],
      :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
    }
}

My model:

class Sound < ActiveRecord::Base
  belongs_to :user

  # for paperclip
  has_attached_file :sound_file,
                    :s3_domain_url => "bucketname.s3.amazonaws.com",
                    :bucket => 'bucketname',
                    :s3_permissions => :public_read,
                    :encode => 'utf8'

  # do not create a sound unless a sound file
  # is present
  validates_attachment_presence :sound_file
end

When the user clicks on this, a file should be downloaded:

   <%= button_to "Download", download_url(sound.id), :method => :get %>

My controller:

def download
    @sound= Sound.find(params[:id])
    data = open(@sound.sound_file)
    send_data data.read, :type => data.content_type, :x_sendfile => true
end

When I look at the logs from heroku, I see this error message:

 Parameters: {"id"=>"5"}
 Started GET "/sounds/5/download" for 76.168.22.71 at 2013-11-16 01:22:17 +0000
 Processing by SoundsController#download as HTML
 Started GET "/sounds/5/download" for 76.168.22.71 at 2013-11-16 01:22:17 +0000
 Parameters: {"id"=>"5"}
 Processing by SoundsController#download as HTML
 Completed 500 Internal Server Error in 6ms
 Completed 500 Internal Server Error in 6ms
 app/controllers/sounds_controller.rb:40:in `download'
 app/controllers/sounds_controller.rb:40:in `download'
 TypeError (no implicit conversion of Paperclip::Attachment into String):
 TypeError (no implicit conversion of Paperclip::Attachment into String):

Any idea what I am doing wrong?

Upvotes: 2

Views: 837

Answers (2)

Christopher Spears
Christopher Spears

Reputation: 1105

Solved this! Here is the download function I used in my controller.

def download
    @sound= Sound.find(params[:id])
    send_file Paperclip.io_adapters.for(@sound.sound_file).path,
      :filename => @sound.sound_file_file_name, 
      :type => @sound.sound_file_content_type,
      :disposition => 'attachment', 
      :x_sendfile => true
end

Upvotes: 1

Christopher Spears
Christopher Spears

Reputation: 1105

So....I partially solved the issue:

def download
    @sound= Sound.find(params[:id])
    send_data @sound.sound_file, :disposition => 'attachment', :x_sendfile => true
end

This does cause a file download, but the downloaded file is a text document with the following written inside:

http://s3.amazonaws.com/bucketname/sounds/sound_files/000/000/005/original/83746__braffe2__pen-writing.wav?1384493473

The good news is that Paperclip seems to be able to find the file. The bad news is that it is just returning a text document instead of a .wav file. Any hints?

UPDATE

Replaced send_data with send file in the controller:

def download
    @sound= Sound.find(params[:id])
    send_file @sound.sound_file.url,
      :filename => @sound.sound_file_file_name, 
      :type => @sound.sound_file_content_type,
      :disposition => 'attachment', 
      :x_sendfile => true
end

Now when I try to download from the app on Heroku, I get this error message:

Sent file http://s3.amazonaws.com/bucketname/sounds/sound_files/000/000/005/original/83746__braffe2__pen-writing.wav?1384493473 (0.2ms)
Sent file http://s3.amazonaws.com/bucketname/sounds/sound_files/000/000/005/original/83746__braffe2__pen-writing.wav?1384493473 (0.2ms)
ActionController::MissingFile (Cannot read file http://s3.amazonaws.com/bucketname/sounds/sound_files/000/000/005/original/83746__braffe2__pen-writing.wav?1384493473):
app/controllers/sounds_controller.rb:40:in `download'

I am pretty sure I am almost there. Any hints? One question I have is what are all of those numbers after '?' in the file path?

Upvotes: 2

Related Questions