Problems With Attachment_fu and a Dedicated Image Model
Ben Scofield, Former Viget
I recently ran across a real head-scratcher with an application I've been working on. I've got a polymorphic relationship from several different models to an Image model, which is implemented with attachment_fu. Each of the polymorphic models can have one and only one image, but those images each have many thumbnails (which are handled via attachment_fu). To start, then, my polymorphic models each include the Imageable module, which in part looks like this:
module Imageable def self.included(base) base.class_eval do has_one :image, :dependent => :destroy, :as => :record # ... end end endThe problem that we saw was that sometimes - for some records, on some pages, but repeatably - the public_filename coming back for a given thumbnail had two size modifiers attached. For instance, what should have looked like /uploads/0000/0123/test_large.png came back /uploads/0000/0123/test_large_large.png. The database records were all correct, and all calls to public_filename directly returned the correct result. After a couple of hackish attempts to work around this, though, I realized that the underlying problem was that, when I eagerly loaded the image record, one of the thumbnails was being returned instead of the parent image. The solution ended up being simple:
module Imageable def self.included(base) base.class_eval do has_one :image, :dependent => :destroy, :as => :record, :conditions => 'parent_id IS NULL' # ... end end endBy adding the parent_id IS NULL condition, the thumbnails are all excluded from any call to record.image, so the only row returned will always be the parent image. Just something to keep in mind for next time!