Handling in-progress ActiveStorage variants

Hello all, I am working on a specific use case with ActiveStorage and I want to be sure I’m not missing an obvious easy way to do it.

I am working on a rails application that uses ActiveStorage for attachments / variants. The application needs to accept pretty large images (e.g. 250mb+ JPEGs), and the app has a page that display thumbnails of uploaded images. When a user uploads an image, they are redirected back to that thumbnail listing page. I have specified preprocessed: true on the thumb variant, and I can see that an activejob gets queued and started to create the thumbnail. However, calling photo.file.variant(:thumb).processed.url runs the processed method found here:

That method determines (correctly) that the variant has not yet been processed, because the active job is still running, so it attempts to create the variant inline with the request. This is what I’m trying to avoid, since at best it results in a very slow server response.

I looked around in that class, and it has a private processed? method that looked useful. I tried using that locally (naughty I know) and I was able to build a helper method that would display a placeholder image for these in-progress variants. Success!

# app/helpers/application_helper.rb
def variant_or_placeholder_url(variant)
  if variant.send(:processed?)
    variant.processed.url
  else
    asset_url("icons/variant_placeholder.svg")
  end
end

# app/views/photos/_photo.html.haml
= image_tag variant_or_placeholder_url(photo.file.variant(:thumb))

Does this seem useful enough to warrant making ActiveStorage::Variant#processed? public? I’m happy to open a PR for that, but since I found no talk about this subject at all I’m not sure if anyone else would find it helpful.

Makes a lot of sense to me, had a similar need recently.

That’s good to hear – I hope my code was helpful in some way.

it’s going to be public soon

Interesting, I think the most useful part of that PR for this case is actually making processed? public, rather than the immediate processing option.

Looks like it was merged in December 2025, though the changes are still on main for Rails 8.2, not the current 8.1 release.

With 250 MB+ images, I’d be hesitant to use process: :immediately, since that means doing the variant processing during attachment. Keeping it in a background job seems like a better fit here.

Once processed? is public, you could check whether the thumbnail is ready without triggering another processing attempt. You’d still need something to refresh the placeholder after the job finishes, but at least there’s no need to call a private method anymore.

For this particular use case, that seems like the more useful change.