Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3 + Paperclip: moving current data to another folder

As i'm new to Rails, I made the mistake of using the default path ( /system/:attachment/:id/:style/:filename ) in 4 different models. Now, i would like to move each model to its own folder but without losing old data.

What is the proper way of handling this? Does Paperclip offer an option to automatically migrate data from old folders?

Thanks.

like image 862
Fernando Avatar asked Nov 30 '25 22:11

Fernando


2 Answers

I had a similar dilemma. We were storing all our attachments in a certain path, and then business requirements changed and everything had to be moved and re-organized.

I'm surprised how little info there is on changing paperclip path and moving files. Maybe I'm missing the obvious?

Like Fernando I had to write a rake task. Here's what my code looks like (attachments model is Attachment, and the actual Paperclip::Attachment object is :file )

task :move_attachments_to_institution_folders => :environment do
attachments = Attachment.all
puts "== FOUND #{attachments.size} ATTACHMENTS =="
old_path_interpolation = APP_CONFIG[ 'paperclip_attachment_root' ] + "/:id_partition.:extension"
new_path_interpolation = APP_CONFIG[ 'paperclip_attachment_root' ] + "/:institution/reports/:id_:filename"
attachments.each do |attachment|
    # the interpolate method of paperclip takes the symbol variables and evaluates them to proper path segments.
    old_file_path = Paperclip::Interpolations.interpolate(old_path_interpolation, attachment.file, attachment.file.default_style) #see paperclip docs
    puts "== Current file path:  #{old_file_path}"
    new_file_path = Paperclip::Interpolations.interpolate(new_path_interpolation, attachment.file, attachment.file.default_style)
    if File.exists?(old_file_path)
        if !File.exists?(new_file_path) #don't overwrite
            FileUtils.mkdir_p(File.dirname(new_file_path)) #create folder if it doesn't exist
            FileUtils.cp(old_file_path, new_file_path)
            puts "==== File copied (^_^)"
        else
            puts "==== File already exists in new location."
        end
    else
        puts "==== ! Real File Not Found ! "
    end
end

The key thing for me was to have paperclip re-calculate the old path by using its default interpolations. From then it was just a matter of using standard FileUtils to copy the file over. The copy takes care of renaming.

P.S. I'm on rails 2.3.8 branch, with paperclip -v 2.8.0

like image 164
mastaBlasta Avatar answered Dec 04 '25 00:12

mastaBlasta


I ended up creating a small rake task to do this. Assuming that you have a model called User and your image file is called "image", place the following code in lib/tasks/change_users_folder.rb

desc "Change users folder"
task :change_users_folder => :environment do
  @users = User.find :all
  @users.each do |user|
    unless user.image_file_name.blank?
      filename = Rails.root.join('public', 'system', 'images', user.id.to_s, 'original', user.image_file_name)

      if File.exists? filename
        user.image = File.new filename
        user.save
      end
    end
  end
end

Them, run rake change_users_folder and wait.

Note that this won't delete old files. They will be kept at the original place and a copy will be created at the new folder. If everything went well, you can delete them later.

And for my future code, i will make sure i always set :path and :url when using paperclip :)

like image 37
Fernando Avatar answered Dec 04 '25 01:12

Fernando



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!