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.