Question: I'm working on a rails 3.2.8 app that will be soon shut down.

This app has a post model that has\_many assets.

The asset model is paperclip managed.

```
class Asset < ActiveRecord::Base
attr_accessible :post_id, :photo
  belongs_to :post                
  has_attached_file :photo, 
                    :styles => {
                      :thumb => '260x260#',
                      :normal => {
                        :geometry => '600x600>',
                      }
                    }
end

```

I need to login in the production environment and run a command that backs up every photo to another folder in the filesystem like this:

```
~/backup-folder/post-name-foo/post-name-foo-1.png
~/backup-folder/post-name-foo/post-name-foo-2.png
~/backup-folder/post-name-bar/post-name-bar-1.png
~/backup-folder/post-name-bar/post-name-bar-2.png
~/backup-folder/post-name-bar/post-name-bar-3.png
~/backup-folder/post-name-baz/post-name-baz-1.jpg

```

Images can be both in png or jpg format, probably also JPG (uppercase), and posts can have an arbitrary number of attachments.

I will need to run the command just once, and I would prefer, if possible to avoid making changes to the application (like installing new gems).

Answer: 
I would use the shell `cp` command to copy the assets to the backup directory; this should be markedly quicker than opening and reading every asset in Ruby:

```
require 'shellwords'

backup_destination = '/home/app/backup_directory'

# create the backup base directory
FileUtils.mkdir_p backup_destination

Post.find_each do |post|
  # change this if you generate your 'nice' post URLs in a different manner
  post_name       = post.to_param
  post_backup_dir = File.join(backup_destination, post_name)

  FileUtils.mkdir_p post_backup_dir

  post.assets.each_with_index do |asset, index|
    file_extension = File.extname(asset.photo_file_name)
    new_file_name  = "#{post_name}-#{index}#{file_extension}"

    # escape spaces in paths
    source_path = Shellwords.shellescape asset.photo.path(:original)
    target_path = Shellwords.shellescape File.join(post_backup_dir, new_file_name)

    output = `cp #{source_path} #{target_path} 2>&1`

    # make sure cp worked correctly
    unless $?.exitstatus == 0
      puts "WARNING: failed to copy asset #{asset.id} from #{source_path} to #{target_path}: #{output}"
    end
  end
end

```
Here is example of how to backup a file using `rake` command, you can enhance its logic for folder backup, I hope this will help

1. Create a rake file inside `<root_folder>/lib/task/photo_backup.rake`.

```
task :photo_backup => :environment do
    require 'rubygems'
    require 'rake'

    # file path on production 
    filename = "post-name-foo-1.png"  
    path_to_file = "#{Rails.root.to_s}/images_folder/#{filename}"

    # backup folder on production
    backup_folder_path = "#{Rails.root.to_s}/backup_folder"
    backup_dir = FileUtils.makedirs(backup_folder_path).first

    begin
       f = File.new("#{backup_dir}/#{filename}", "w+")
       data = open(path_to_file).read
       f.write(data)
    rescue Exception => exp
       puts("Error message : #{exp.message}")
    ensure
       f.close unless f == nil
    end
end

```
2. From console execute below command inside your project-root dir.

```
rake photo_backup

```