Ruby Forum Ruby on Rails > Copying attachment_fu file uploads

Posted by Rob Lee (monkeyhelper)
on 10.05.2007 00:38
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 ?
Posted by Rick Olson (Guest)
on 10.05.2007 07:10
(Received via mailing list)
> 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 Olson
http://lighthouseapp.com
http://weblog.techno-weenie.net
http://mephistoblog.com
Posted by Rob Lee (monkeyhelper)
on 10.05.2007 18:11
Rick Olson 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
Posted by Rick Olson (Guest)
on 10.05.2007 22:23
(Received via mailing list)
On 5/10/07, Rob Lee <rails-mailing-list@andreas-s.net> 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 Olson
http://lighthouseapp.com
http://weblog.techno-weenie.net
http://mephistoblog.com
Posted by Bill Harding (wbharding)
on 24.09.2007 09:43
(Received via mailing list)
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
Posted by Terry Shuttleworth (itsterry)
on 19.01.2008 01:00
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


Posted by Christophe Porteneuve (tdd)
on 04.02.2008 14:09
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…
Posted by Christophe Porteneuve (tdd)
on 04.02.2008 14:12
Er, sorry about that, the post needs a couple clarifications:

Christophe Porteneuve 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
Posted by Bill Harding (wbharding)
on 13.10.2008 02:07
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