views:

403

answers:

2

Hi,

I've got a nice little "photos" class that has attached images. When I go to the page to sort the photos' order, it iterates though each photo, sets the new "sort" value, and saves it. All good so far.

Problem is, I've noticed this behavior is fairly slow. Turns out, attachment_fu reloads the thumbnail on every save - regardless of whether or not there's new image data to work with.

Obviously this system has been well-thought-out, so I'm only left to assume that a provision exists for this situation. How do I tell attachment_fu not to regenerate the thumbnails when it's not appropriate?

Thanks, --Matchu

Edit: I just remembered that, for this particular situation, I can use update_attribute to dodge all the validations and other callbacks. However, this isn't really a viable answer to the whole big scenario. What am I missing?

+3  A: 

Went in and hacked attachment_fu a bit, and rewrote the save_attachment? behavior. Pretty much, I added some new conditions: in addition to a temp file existing, one of the following must be true:

  1. No file for the image already exists (using the full_filename attribute).
  2. The image data was explicitly updated using the uploaded_data= method.
  3. The image is a thumbnail.

It passes all three test cases - new photo uploads, edit photo images, and editing non-image photo data - but I haven't really tested this out in the wild just yet. I'll probably have to make a few fixes; we'll see what happens.

Matchu
+1  A: 

The only moderately useful thread I've seen on this topic is here:

http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/709d97e06b373786

I think Matchu's solution is probably the correct one with a quick review of the attachment_fu code. I'd love it if Matchu could share a patch or a snippet of his modified save_attachment? method. I'm about to dig into this on my own, since this has become a problem for me and it'll probably be less work than replacing attachment_fu entirely...

Update

With Matchu's outline, I came up with a short (if inelegant) solution that seems to work after light testing.

I modifed save_attachment? in attachment_fu/attachment_fu.rb:

def save_attachment?
  return false unless (thumbnail || !full_filename || @active_upload) #added
  File.file?(temp_path.to_s)
end

... to check the conditions Matchu laid out. I couldn't come up with an elegant way to tell whether data had been passed along to the uploaded_data= setter method (if anyone has a better way to do this, I'm all ears; I'm still a ruby/rails noob) so I also added a line to uploaded_data= to set the global variable @active_upload:

def uploaded_data=(file_data)
  return nil if file_data.nil? || file_data.size == 0
  self.content_type = file_data.content_type
  self.filename     = file_data.original_filename if respond_to?(:filename)
  @active_upload=true # added
  if file_data.is_a?(StringIO)
    file_data.rewind
    self.temp_data = file_data.read
  else
    self.temp_path = file_data
  end
end

Hope that helps, and if anyone has a more elegant way to handle what I did there with the global variable, I'd love to hear it.

sstrudeau
My approach was very, very similar. I made my own branch on Github, and added some tests, too. Some other branches pulled in the update, but I don't think the main branch did. http://github.com/matchu/attachment_fu/tree/master
Matchu