Change Paperclip secrets the hard way

So you screwed up and copied Paperclip secrets from one project to another. Here is a semi-automatic, painful way to migrate your existing attachment files to new locations.

You need to follow this step by step, do not just copy the whole thing into the console!

# 1. Get old paths by doing something like this on the console:
old_paths = ModelWithAttachment.all.collect { |m| [m.id, File.dirname(m.image.path(:original)).gsub(/original$/, '') ] if m.image.file? }.compact.uniq

# 2. Now change the Paperclip secret on the console (just paste the new initializer) and once more type:
new_paths = ModelWithAttachment.all.collect { |m| [m.id, File.dirname(m.image.path(:original)).gsub(/original$/, '') ] if m.image.file? }.compact.uniq

# 3. Now turn all absolute paths in the arrays above into relative ones (use search + replace).
#    Usually you want to replace this part of the paths: '/opt/www/www.project.de/releases/20110816100321/'

# 4. Also change the directory in the new_paths array so they are all saved to a separate folder.

# 5. Now paste the following script into the console.
#    Attention, the Gnome terminal likes to eat characters when pasting long scripts!
#    Better copy this file to the user home and require it from there.

old_paths_map = Hash[*old_paths.flatten]
new_paths_map = Hash[*new_paths.flatten]

old_paths_map.each do |id, old_path|
  new_path = File.dirname(new_paths_map[id])
  FileUtils.mkdir_p new_path
  p `cp -R "#{old_path}" "#{new_path}"`
end

# 6. After the script has run make sure you compare at least the sizes of old and new folders. Better look into the directory structure, too.

# 7. Now you can switch the folders and remove the old one. Also switch your code to the new secret and deploy your new code!
Henning Koch Over 13 years ago