Moving attachment_fu files from the local filesystem to Amazon S3

attachment_fu may not be the in-thing any more but there are still a lot of sites out there using it. And every now and then you realise, far too late, that you should have used S3 instead of the local filesystem.

Switching is easy – just change the :storage parameter to :s3. But before you can do that, how do you get the existing files onto S3 in the first place?

Well, here’s your answer.

Before you change the storage parameter, create you S3 account and a bucket to store your files.

Then add a new rake task to your application, looking something like this:


  desc "Upload files to S3"
  task :upload_files_to_s3 => :environment do

    AWS::S3::Base.establish_connection!(
      :access_key_id => 'MYACCESSKEY',
      :secret_access_key => 'MYSECRETKEY')

    Model.find(:all).each do | user |
      filename = "/home/user/app/current/public#{model.public_filename}"
      puts "Migrating model #{model.id} - #{filename}"
      if File.exists?(filename)
        AWS::S3::S3Object.store("/models/#{model.id}/#{model.filename}",
          open(filename),
          'my_bucket',
          :access => :public_read)
        puts "...migrated"
      else
        puts "...not found"
      end
    end
  end

In other words;

  • connect to S3
  • for each “model” instance, find the attachment on the local filesystem
  • if found, then push it to S3, using /models/id/filename as the key (where models is your table name)

As soon as you’ve done that, switch the :storage to :s3 and redeploy your app (not forgetting your config/amazon_s3.yml file). And, with a bit of luck, you should see your files being served from Amazon’s servers, instead of your own.

Tags: , ,

This entry was posted on Tuesday, November 24th, 2009 at 8:26 pm and is filed under Ruby on Rails and Software Development. You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.

Comments are closed.