Great tutorial! The direct route helper works great for my production environment, where I use Active Storage with a S3 service and Cloudflare CDN. However, in my development environment I have this
config.active_storage.service = :local
in storage.yml:
local:
service: Disk
root: <%= Rails.root.join("storage") %>
Now, when I run the app in development, I get this error as soon as I try to display an image:
To make this work, it was required to add the "only_path: true" parameter to route_for, i.e.
direct :rails_public_blob do |blob|
if Rails.env.production?
File.join("cdn.example.com", blob.key)
else
route_for(:rails_blob, blob, only_path: true)
end
end
Without "only_path: true", I was getting this message:
Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
After this was fixed, howerver, I noticed that the rails_public_blob helper started returning a path to the "master" image and not to the variant, i.e.
force the creation of the variant:
current_user.avatar.variant(variant_options).processed
Great tutorial! The direct route helper works great for my production environment, where I use Active Storage with a S3 service and Cloudflare CDN. However, in my development environment I have this
config.active_storage.service = :local
in storage.yml:
local:
service: Disk
root: <%= Rails.root.join("storage") %>
Now, when I run the app in development, I get this error as soon as I try to display an image:
undefined method `signed_id' for #ActiveStorage::Variant:0x00007f357...
the line error being shown is precisely the direct route in config/routes.rb:
The only difference I can see is that I am using variants, i.e., outside my views I have this:
Rails.application.routes.url_helpers.rails_public_blob_url(current_user.avatar.variant(variant_options))
Any ideas on what might be happening?
Thanks!
Hi Eduardo
good point. If you're using variants, try calling
.blob
on the variant before you pass your variant as an argument to the URL helper:You might also need to add
.processed
to the mix (depending on how/when you process your variants):Let me know if that worked.
Thank you for your kind response.
To make this work, it was required to add the "only_path: true" parameter to route_for, i.e.
direct :rails_public_blob do |blob|
if Rails.env.production?
File.join("cdn.example.com", blob.key)
else
route_for(:rails_blob, blob, only_path: true)
end
end
Without "only_path: true", I was getting this message:
Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true
After this was fixed, howerver, I noticed that the rails_public_blob helper started returning a path to the "master" image and not to the variant, i.e.
force the creation of the variant:
current_user.avatar.variant(variant_options).processed
blob = current_user.avatar.variant(variant_options).blob
image_path = Rails.application.routes.url_helpers.rails_public_blob_url(blob)
image_path points to the master image, not to the variant. This wasn't happening before. Any ideas? :)
Thanks for any insight!
-Eduardo
Hi Eduardo
I just updated the post with the solution for variants. Please have a look. It appears variants have their own URL helper
rails_representation_url
.Thank you, Florin! It works wonderful now. I still needed to add "only_path: true" to "route_for", i.e.:
route_for(route, blob, only_path: true)
Thanks for the great post and the generous assistance. 😊