During my experimenting with ActiveStorage I came to learn that while it’s been in Rails since version 5.2, it still lacks both validations and callbacks for you attached blobs. Luckily the there’s a community maintained gem with some basic validations, called active_storage_validations, the callbacks you have to add on your own.
To understand the challenge, let us first look at the flow of attaching an ActiveStorage blob to a new ActiveRecord model (let’s call it
- Blob gets uploaded
- Blob is attached to a in-memory instance of the new
- If the
Userobject is valid, it, and the
- Asynchronously, the
Analyzercompletes it work, and updates the
Blobwith new metadata.
I want my user to be notified after the blob gets updated with new metadata, so I can refresh the Elasticsearch index with the new information. And while the association model between my User and Blob,
ActiveStorage::Attachment has a
belongs_to :record, touch: true, nothing happens if a blob gets updated.
So let us utilize some of the magic in Ruby, and add some functionality to
The above code goes into
config/initializers/active_storage_touch_records_after_analyze.rb. After a reload, you can verify that it’s working by calling
.analyze on one of your blobs.
to_prepare: Run after the initializers are run for all Railties (including the application itself), but before eager loading and the middleware stack is built. More importantly, will run upon every code reload in development, but only once (during boot-up) in production and test.
Note that I’m using a
.to_prepare block around this initializer. This ensures that every bit of Rails is loaded enough, so I can safely inject my code. It also gives the benefit of being reloaded in development, which is quite helpful when making changes to initializers. For more in-depth information on the Rails boot-up stages, check out the official documentation.