Use original file as default_url?

Hi - I am working on updating to Shrine 3 from 2.x and one thing that I was hoping to be able to do was to use the original file_url in the cases where derivatives like file_url(:small) have not yet been created due to background processing. I realize that I could use a static image with the default_url plugin, but I am hoping to just fall back to the original. Can this be done?

In case anyone comes across this by search, I think I solved it myself.

  Attacher.default_url do |derivative: nil, **|
    record.file_url if derivative
  end

Good that you found a solution. Note that you wanted to keep it model-agnostic, you can also call Attacher#url directly:

Attacher.default_url do |derivative: nil, **|
  url if derivative
end
1 Like

Another thing you might want to consider is falling back to an on-demand derivative if the derivative you’re requesting is not yet available.

  Attacher.default_url do |derivative: nil, **|
    # replace 600, 600 with whatever :small is
    file.derivation_url(:thumbnail, 600, 600) if derivative
  end

  derivation :thumbnail do |file, height, width|
    # do whatever pipeline processing you do here
  end

There is a shrine-rails example repository which has a good process for doing this, which is where I learned about the possibility.

2 Likes

Where is that dynamic thumbnail stored? Does it get replaced at the time of promotion? And wouldn’t this kinda defeat the purpose of doing async/background promotion/processing?

There are a number of different options, but for the most part it’s generated on the fly, but only if the background job hasn’t completed yet. This way you aren’t serving the full-size image to the user, you display a small thumbnail still, but one that’s generated on demand.

The next time the user loads the page, if the background job has completed, then that is the version that will be displayed, as the default_url fallback will never get called.

I like this approach because it offers a fallback to a processed version of the image, instead of the full size. But if the processed version is available, it serves that one up instead.

There are several options for storing the dynamic thumbnail including not storing it at all. It doesn’t get replaced at promotion because it’s created on demand typically after promotion of original file and only stored if you choose it to be. For more details on on-the-fly processing and dynamic thumbnail generation see uploading section in derivation_endpoint documentation.

Will it defeat the purpose? Not really because you can implement a more complex derivation strategy to better balance processing and storage costs. Let’s say for every image you require 5 different sizes but typically only 2 of the 5 are used often. You can process those 2 derivatives in background job and do the remaining 3 derivatives with on-the-fly processing and only storing it once created. This way you can better optimize resources and costs for your use case.