I’m using attachment_fu to provide file uploads/processing for a product
class. I’d like to create a cloned version of a product with a copy of
the initial versions image files. I don’t want the original version to
share the cloned versions file but have new ones that are copies.
I could copy all images for the product and create new rows in the
product_images table (the one used by attachment_fu) but this seems a
bit inelegant, does anybody know a ‘better’ way or if attachment_fu
supports this functionality in some way ?
I could copy all images for the product and create new rows in the
product_images table (the one used by attachment_fu) but this seems a
bit inelegant, does anybody know a ‘better’ way or if attachment_fu
supports this functionality in some way ?
Nope, it doesn’t support that. But if it did, it’d probably create
new rows in your attachment table and copy over the attachments to the
new copied records.
Nope, it doesn’t support that. But if it did, it’d probably create
new rows in your attachment table and copy over the attachments to the
new copied records.
For reference, I ended up adding this to attachment_fu.rb which I
believe should work with all the backends for attachment_fu :
def create_clone
c = self.clone
self.thumbnails.each { |t|
n = t.clone
img = t.create_temp_file
n.temp_path = img.path
n.save_to_storage
c.thumbnails<<n
}
img = self.create_temp_file
c.temp_path = img.path
c.save_to_storage
c.save
return c
end
}
img = self.create_temp_file
c.temp_path = img.path
c.save_to_storage
c.save
return c
end
You should probably send ‘img’ to #temp_path. Those are TempFile
objects, and they will automatically be deleted when they’re garbage
collected. So, you’ll lose the reference to them by passing img.path,
and there’s a chance the file won’t be there when you go to save it.
If you pass the TempFile instance, it won’t get garbage collected
until after the rails request has completed.
Er, sorry about that, the post needs a couple clarifications:
Christophe P. wrote:
def clone_with_file
result = clone
result.temp_path = create_temp_file
result
end
This is mostly intended to be private.
def clone_with_files
self.class.transaction do
result = clone_with_file # I had forgotten to prune out extra args here…
if attribute_names.include?(‘parent_id’)
result.thumbnails = thumbnails.map &:clone_with_file
end
result
end
end
This is essentially the method you’d call from outside. It will clone
thumbnails if the table for your images features a standard parent_id
field, hinting at thumbnail setup (I could also have checked
attachment_fu_options, but felt like pulling a quick trick…).
You’re better off leaving the save_to_storage code out, as it will get
called automatically after save, AND if called before that you’ll get
weird file names due to zero ID before save. So your file will get
saved to a first name that is incorrect, and a second one that is
correct, post-DB-save.
The code for cloning thumbnails and the main image is redundant, too,
and it won’t work on images with no thumbnail setup. Here’s how I went
about it, as a suggestion (I stripped the custom code I added to update
the reference to the parent model, which was besides the point here):
def clone_with_file
result = clone
result.temp_path = create_temp_file
result
end
def clone_with_files
self.class.transaction do
result = clone_with_file(new_draft, strict)
if attribute_names.include?(‘parent_id’)
result.thumbnails = thumbnails.map &:clone_with_file
end
result
end
end
Just a thought…
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.