A Convention for Active Storage Attachment Management

Active Storage is a pretty nice addition to Rails. Essentially you’re given an out-of-the-box polymorphic solution to managing ANY type of attachment. Rails will handle the processing and storing of attachments along with extra stuff such as metadata extraction. Super cool.

The Problem

Management of Active Storage attachments in a way that feels Railsy is a different story though. Let’s say you have a Profile resource that uses a Picture attachment.  When viewing profile#show wouldn’t it be nice to just delete the picture from there? Where would the actual act of destroying an attachment live?

Attachment management seems strange because it FEELS like it’s just another aspect of your resource but it’s not.

I tried a couple options that didn’t seem to be right…

  • Add logic to the resource controller’s destroy action to delete an instance of the resource OR optionally remove just the resource’s attachment(s)
  • A universal attachment controller.  CRUD requests are sent to AttachmentController and operate using a combination of attachment ID and type

I think both of those options felt wrong because we either end up with controller actions concerned about things they shouldn’t really know about OR we end up with a “universal” controller that will likely become littered with callbacks for many different resources.

A Convention I’ve Adopted

For now when I have a resource using Active Storage attachments I create namespaced controllers (and routes) for each attachment type under the resource they support. 

So in the case of the Profile and Picture example above I’d have something like this: 

  • app/controllers/profiles_controller.rb
  • app/controllers/profile/pictures_controller.rb

This is nice because PicturesController can have callbacks or prerequisites (think authentication) that are specific to the app OR add things that are specific to pictures without polluting intent.

Code + Walk-through

Checkout the walletapp repo for a demo I made using this technique.  For now please check the commit history and shortly I’m going to add a tutorial on how to setup an app from scratch that has attachments and attachment management using the nested controller approach.

Storage.