I'm currently using the awesome attachment-fu plugin for a Rails app, but as a novice developer, I've never encountered a scenario like the one I've found myself in. Essentially, I'm using the attachment-fu plugin on two levels. The first is for user avatars in the user class. The second is to allow file attachments (PDFs, etc) in a messaging system. My question is what the best use practice would be in these situations to remain DRY, clear, and consistent. Clearly it would make no sense to define and execute the plugin in both classes, but there's something deeply strange to me (possibly unfounded) about just going ahead and setting it all up in the godly Application class. Is there something in between, or is the parent class the way to go?


+2  A: 

Is "outsourcing" avatar support entirely to Gravatar an option? There are some Rails plugins that will display avatars hosted by Gravatar. You might not need to re-invent the wheel there.

John Topley

Wow! Gravatar's really neat! I'll be saving that one in my back pocket for future projects but I don't think it's the solution I'm after for this current one, unfortunately.

Bryan Woods

I would lean towards using a parent class, with subclassing for the different ways you intend to actually use the attachments in your application. It may not be the DRYest solution available, however, it lends itself to a logical pattern rather well.

+3  A: 

What's the DRY issue with defining the attachment_fu settings twice?

Unless the files are of the same type and being stored in the same place, you're not going to be repeating anything in the configuration.

Sure, you'll have two has_attachment declarations, but the options will mostly differ (one declaration for your avatars and the other for your pdf's etc.

99.99% of the code to handle attachment will be buried in the attachment_fu libs, your configuration code should be pretty DRY by default =)

Cheers Dave

Dave Smylie

Couldn't you use Polymorphic Associations?

I'm about to hit this in my app with attachment_fu, so I'm not exactly sure on attachment_fu, but for the old school File Column plugin, I would use Polymorphic Associations.

My "file" model would be:

    class FileUpload < ActiveRecord::Base
      belongs_to :fileable, :polymorphic => true
      file_column :name

and then any models that needed a file attachment would be like:

    class Company < ActiveRecord::Base
      has_many :file_uploads, :as => :fileable

File Column is no good anymore as it borks on Safari 3.x and is no longer maintained. It was nice and simple though... Ah, the good old days...

Dan Harper - Leopard CRM
+2  A: 

What wfarr is describing would be single table inheritance, which is what I currently do in this situation. I have one table for Assets which contains all the necessary attachment_fu columns, plus an extra column called type, which will hold the actual model name. I have a model for assets and additional models for specific upload types that inherit from assets:


class Asset < ActiveRecord::Base
  ... attachment_fu logic ...


class Avatar < Asset
  ... avatar specific attachment_fu logic ...


class PDF < Asset
  ... PDF specific attachment_fu logic ...
Damn, that's clever, thanks a lot!

For what it's worth, I think Patrick Berkeley has done a good job with handling multiple attachments through the Paperclip plugin. He's outlined his work here:

The Pied Pipes