I made the mistake of using the default Paperclip url/path for multiple models, which is problem if an user upload a file with the same name and id, causing a conflict. Also, using the same directory for different models is kind of messy.
Here are the steps that i took to fix this problem:
1. Change the path/url in model
Before:
class User < ActiveRecord::Base has_attached_file :image end [/ruby] After: [ruby] class User < ActiveRecord::Base has_attached_file :image, :path => ":rails_root/public/system/users/images/:id/:style/:filename", :url => "/system/users/images/:id/:style/:filename" end
This will make them to be stored in public/system/users/images/. If you have other models like Post or Article, edit them too but use different paths.
2. Move your current data
If you already have some files, it’s time to move them as Paperclip won’t do it for you. To do it i created a rake task. Place it in lib/tasks/copy_paperclip_data.rake:
desc "Copy paperclip data" task :copy_paperclip_data => :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 image = File.new filename user.image = image user.save image.close end end end end
You probably have to adapt this in case you are working on another model or field. In this case, i’m working on model Users and field image.
Note that i’m copying data. In case something goes wrong, you can revert it back. Remove it after you’re done.
Now simply run:
rake copy_paperclip_data
Hope this helps you.
Hi.
I dont understand what your line 8 means. The filename doesnt exists because thats what we are attempting to do here. I dont get your code running, when i execute line 9, i got “No such file or directory”, because the old image doesnt exists in new directory but it does in the old directory.
Any suggestions?
Thanks
Icaro,
filename variable is supposed to be the full path of your *old* directory. In my code I’m considering that it’s currently located in the default paperclip path.
If your files are located elsewhere, like public/system/other/directory/, then change line 6 to match it.
Line 8 is simply checking if file exists in old directory.
Perfect, now i understand everything.
In my case, i need to delete the old original image. So i added FileUtils.rm image. This wont delete the entire folder, but the original image is using lots of hd space.
Cheers
I have one issue. I want to make a copy of my previous image. By default the images are stored in the public folder. As soon as I make the clone of my existing image it start searching the image with the new id, but that folder doesn’t exist. For eg: if the id of my previous image is 5, then on cloning it start searching in the image in new folder with id = 6. But on cloning no such folder with id==6 creates. So I just want create a new folder with new id on cloning the image. How can I chieve that.
I’m not sure if i understand your problem. Why exactly are changing the id of your images?
This tutorial is simply to copy images to a new path. So you will only update your images, keeping the same id of course.
Ok is there any way to copy the same image with different id’s. I am going to paste the code which will make you understand what I want to tell you.
I am creating an offer having an image attach with it using paper clip. As soon as I save that offer in the db I can view my attached image on show page. As my image is saved in following path and url:
offer.rb
has_attached_file :image,
:styles => {
:thumb=> “100×100>”,
:small => “150×150>”,
:medium => “300×300>”,
:large => “400×400>”
},:path => “:rails_root/public/assets/products/:id/:style/:basename.:extension”,:url => “/assets/products/:id/:style/:basename.:extension”
Now second time I want to clone that offer with same data and image. I am just copying all the things of particular offer and saving it with new id. Everything is saving fine, and the image is saving with new id but there is not any folder with that id in my public folder which used to create automatically using paper clip, hence it is not displaying any image. The code which I written in my controller is as follows:
offers_controller
@deal = Offer.find(params[:id])
@attr = { :nameofdeal => @deal.nameofdeal, :value => @deal.value, :offercategory => @deal.offercategory, :image_file_name => @deal.image_file_name,:type => ‘image/png’}
@offer = Offer.new(@attr)
So can you please help me how to achive that so that it will create a folder with the next id having the same image, or the path refer to the previous offer’s image whose folder is present in the public folder?
Any help will be appreciated.
Hi Fernando, I used your code and slightly improved it for my project. You can see my version here: http://goo.gl/oyy2x . I credited you for your work, obviously – Thanks for sharing!
Andrea Schiavini
Nice but the name of the file should be
=> copy_paperclip_data.rake
instead of
=> copy_paperclip_data.rb
Here is another rake example for copying images using paper clip
namespace :image_data do
#bundle exec rake image_data:copy_paperclip_data
desc “Copy paperclip data”
task :copy_paperclip_data => :environment do
@users = User.where([‘id = ?’,1])
@users.each do |user|
if user.images.present?
user_img = user.images.first
# filename = Rails.root.join(‘public’, ‘system’, ‘images’, user.id.to_s, ‘original’, user_img.image_file_name)
filename = user_img.image.path
if File.exists? filename
puts filename
image = File.new filename
image1 = user.images.new
image1.image = image
image1.save
puts image1.id
end
end
end
end
end