Close and Go BackBack to Viget

Problems With Attachment_fu and a Dedicated Image Model

Ben Scofield
Ben Scofield, Development Director, May 19, 2008 0

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
end

The 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
end

By 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!

Trackback URL: http://www.viget.com/trackback/1119/

Comments for this entry were closed after 60 days.

A Development Community for Viget Labs and Beyond

Every team member here at Viget Labs strives to be an innovator. We members of the development team are no different - that's why we're constantly engaging in community discussions and exploring the unknown that is the next generation of open-source web applications.

Viget Is Hiring!

Viget has job openings for Ruby Developers, Interns, and Front-End Developers. Learn More »

Recent Comments

I think that polymorphic_url(@commentable, :anchor => “comment_#{@comment.id}") should work. You can also refactor the “comment_#{@comment.id}” to a separated method, like dom_id, which returns the dom identifier of the comment.