I'm switching to Rails Active Storage to handle upload and storage of images locally (using the disk service) for a product catalog, and I'm having trouble getting a usable url to the image to feed into an <img>
tag. I'm using React on the frontend, so I can't (easily) use Rails helpers to generate the tag.
ActiveStorage puts the files in /public/images
. I can hardcode relative links to the files (i.e. http://localhost:3000/images/Ab/CD/AbCDEfGhIjkL
) and it works fine.
Relevant snippet from Product.rb
:
class Product < ApplicationRecord
attr_accessor :image_url
has_one_attached :image
def as_json(options)
h = super(options)
if self.image.attached?
h[:image_url] = ActiveStorage::Blob.service.service_url(self.image.key)
end
h
end
end
as_json
produces a JSON object to feed to React that has an entry image_url
that is used for the <img>
's src
attribute. With the code above, image_url
contains the full path to the file (i.e. http://localhost:3000/srv/www/rails_app/public/images/Ab/CD/AbCDEfGhIjkL
). Using url_for
in the view produces the same result. I want it to only contain the path relative to rails root.
I could manipulate the string to remove everything before the relative path, but I foresee this causing bugs in the future if anything ever changes, so I'd much rather find a way to get ActiveStorage to just generate an appropriate string for me.
Thanks!
You need to use the routes helper to build of a URL to your Rails app.
https://guides.rubyonrails.org/active_storage_overview.html#linking-to-files
class Product < ApplicationRecord
attr_accessor :image_url
has_one_attached :image
def as_json(options)
h = super(options)
if self.image.attached?
h[:image_url] = Rails.application.routes.url_helpers.rails_blob_path(self.image)
end
h
end
end