Search code examples
ruby-on-railsrakecarrierwaverackspace-cloudfog

How to upload images to Rackspace Cloud Files using rake task?


I'm trying to use Fog /Carrierwave/ with Rackspace Cloud Files. I have bunch of uploaded images in my production server. I'm trying to upload these images to Rackspace Cloud Files using below rake task.

desc 'Transfer photos to rackspace'
task :photos => :environment do
  photos = Photo.order(created_at: :desc).limit(10)
  photos.each do |photo|
    if photo.attachment?
      photo.attachment.recreate_versions!
      photo.save!
    else
      puts "================================= ATTACHMENT NOT FOUND: ID: #{photo.id}"
    end
  end
end

But I get following errors:

rake aborted!
undefined method `body' for nil:NilClass
/home/zeck/.rvm/gems/ruby-2.0.0-p247@rails-4-1/gems/carrierwave-0.9.0/lib/carrierwave/storage/fog.rb:227:in `read'
/home/zeck/.rvm/gems/ruby-2.0.0-p247@rails-4-1/gems/carrierwave-0.9.0/lib/carrierwave/uploader/cache.rb:77:in `sanitized_file'
/home/zeck/.rvm/gems/ruby-2.0.0-p247@rails-4-1/gems/carrierwave-0.9.0/lib/carrierwave/uploader/cache.rb:116:in `cache!'
/home/zeck/.rvm/gems/ruby-2.0.0-p247@rails-4-1/gems/carrierwave-0.9.0/lib/carrierwave/uploader/versions.rb:225:in `recreate_versions!'
/home/zeck/code/bee/lib/tasks/bee.rake:9:in `block (4 levels) in <top (required)>'
/home/zeck/.rvm/gems/ruby-2.0.0-p247@rails-4-1/gems/activerecord-4.0.1/lib/active_record/relation/delegation.rb:13:in `each'
/home/zeck/.rvm/gems/ruby-2.0.0-p247@rails-4-1/gems/activerecord-4.0.1/lib/active_record/relation/delegation.rb:13:in `each'
/home/zeck/code/bee/lib/tasks/bee.rake:7:in `block (3 levels) in <top (required)>'
/home/zeck/.rvm/gems/ruby-2.0.0-p247@rails-4-1/bin/ruby_noexec_wrapper:14:in `eval'
/home/zeck/.rvm/gems/ruby-2.0.0-p247@rails-4-1/bin/ruby_noexec_wrapper:14:in `<main>'

It means images not stored in Rackspace Cloud Files. You guys have similar rake task for it? Please share it to me. Or guide me.

Thank you for advice :D


Solution

  • When you change the storage of a CarrierWave uploader from :file to :fog, it loses track of the original uploaded paths of the image files, so methods like recreate_versions! and store! won't be able to find the files to upload.

    If you tell CarrierWave the old paths manually, it'll upload them to Cloud Files for you:

    desc 'Transfer photos to rackspace'
    task :photos => :environment do
      photos = Photo.order(created_at: :desc).limit(10)
      photos.each do |photo|
        if photo.attachment?
          # If you've overridden the storage path in the uploader, you'll need to
          # use a different path here.
          #
          # "photo[:attachment]" is used to get the actual attribute value instead
          # of the mounted uploader -- the base filename of the attachment file.
          path = Rails.root.join('public', 'uploads', photo[:attachment])
    
          unless path.exist?
            puts "#{path} doesn't exist. Double check your paths!"
            next
          end
    
          photo.attachment = path.open
          photo.save!
          puts "transferred #{photo.id}"
        else
          puts "================================= ATTACHMENT NOT FOUND: ID: #{photo.id}"
        end
      end
    end