I use Carrierwave to do file uploads in my Rails app.
When replacing an already uploaded image, the browser still renders the cached original image to the user. Only after hard-refreshing (Cmd-Shift-R on Mac) it renders the new one.
I read here (Stop images from caching in Rails and browser?) that Rails would attach the image's "last updated" timestamp to the URL, but it seems it doesn't in my app:
Maybe this changed meanwhile (the mentioned post is from 2009)? And how would that be fixed today? Thank you.
image_tag
uses asset_path
to calculate final image path (in case it is from asset pipeline), but neither of those add cache buster timestamp.
When image is in asset pipeline and asset digests are enabled - a checksum will be added to file name by asset compilation. For uploaded images it's a task of your image uploading library or yourself.
For example (popular in the past) library paperclip used to save image timestamp in <attachment>_updated_at
attribute and add it to generated links.
For carrierwave it's possible to include timestamp in file name at upload like:
class PhotoUploader < CarrierWave::Uploader::Base
def filename
@name ||= "#{timestamp}-#{super}" if original_filename.present? and super.present?
end
def timestamp
var = :"@#{mounted_as}_timestamp"
model.instance_variable_get(var) or model.instance_variable_set(var, Time.now.to_i)
end
end
Or make it generate unique filenames by some other algorithm.
Anyway using original user-provided filename in your storage is usually not a good idea from security point of view (for example someone can upload nasty_xss_hack.html
).
Other option - is to add timestamp yourself, model's updated_at.to_i
is not ideal (usually model is updated more othed than the image), but will have the job done.