Copying attachment_fu file uploads

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.


Rick O.
http://lighthouseapp.com
http://weblog.techno-weenie.net
http://mephistoblog.com

Rick O. wrote:

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

Thanks for posting this! I added this in, with Rick’s suggested
modifications, and it seems to do exactly what we were looking for.

Saved me about a day of figuring out how to implement the same thing
myself.

–Bill

On 5/10/07, Rob L. [email protected] wrote:

    }

    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.


Rick O.
http://lighthouseapp.com
http://weblog.techno-weenie.net
http://mephistoblog.com

Sorry to be dim, but could someone post exactly the code which worked
and where in the attachment_fu.rb file it sits?

I’ve tried lots of different ways, and although the image file appears
to save, I keep getting a weird IOError error on saving the object
itself

Thanks in advance.

Terry

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…).

'HTH


Christophe

Faster version here:
http://www.williambharding.com/blog/rails/rails-faster-clonecopy-of-attachment_fu-images/

Bill Harding wrote:

Thanks for posting this! I added this in, with Rick’s suggested
modifications, and it seems to do exactly what we were looking for.

Saved me about a day of figuring out how to implement the same thing
myself.

–Bill

About the code you posted:

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…