I have a quite long slideshow of images, all rendered via the awesome Paperclip.
Those images won't change very often, so I'd like to make use of browser caching.
Problem is Paperclip appends a unique load id to the image url.
(eg: pancakes.png?1275839986)
Is there any way to prevent this from happening?
Thanks!
When specifying the image url using:
UrModel.image.url(:style)
# results in: /system/model/000/001/style/style.png?<atimestamp>
Pass in a second parameter which indicates whether or not to include the timestamp:
UrModel.image.url(:style, false)
# results in: /system/model/000/001/style/style.png
Read more about paperclips caching helper: https://github.com/thoughtbot/paperclip/wiki/Tips
That numeric suffix is stored in the database itself by paperclip and is not unique per page load. It's there for caching reasons, actually.
Related
I'm building a webapp which is offline available.
Therefore I need urls to images and videos were not expiring at any time.
ActiveStorage is not build for that case.
So I build my own media controller for serving images and videos based on the url params
get '/media/:kind/:type/:size/:token'
# /media/video/mp4/middle/ABC123
# /media/image/logo/large/ABC124
There is a MediaObject with a unique token. With the params I get the right variant of the image or the converted video file, look for the path of the blob file, seasoned with a quick lookup what filetype it is and serving it.
path = ActiveStorage::Blob.service.send(:path_for, variant_by(size, type).key)
send_file path, type: content_type, disposition: 'inline'
everything is working good, very good. The images and videos got a cacheable (better looking) permanent url.
Now there is an issue with Safari. Every browser can handle the mp4/webm file the controller returns. Except of safari. The video cannot be watched in the browser.
I'm guessing, there is something missing in the headers.
But I cannot find the place in active storage where the videos served.
When I use the default way
# example
Rails.application.routes.url_helpers.url_for(video.mp4)
the video can be played inline.
I've tried to add the content-length to the response header, add range infos and status :partial_content, add the file extension to the url, but nothing works.
The mime type is correct.
Rails 6 introduced a public option in storage.yml. Set it to true to override the expiring URL stuff: https://edgeguides.rubyonrails.org/active_storage_overview.html#public-access
Also, if you're still on Rails 5.2, you should be able to use:
rails_blob_url(imageable.image, disposition: :attachment)
I have this kind of hot fix:
= image_tag "#{current_candidate.profile.photo_url}?stamp=#{SecureRandom.hex}"
The reason for this is that I made a "crop" feature, and when users recrop their photo - old version gets displayed from browser cache.
Anyway.
This photo_url is called in many places, and rather than making a helper & call it everywhere I thought it would be nice to configure uploader to do that.
Is that possible?
Note: filename can't be random. For other reasons.
I would imagine it has something to do with overriding photo_url method.
According to the Paperclip S3 Docs one can specify the :url option in the config which has four possible values. There are comments related to this options that say:
The fourth option for the S3 url is :asset_host, which uses Rails' built-in asset_host settings.
To get the full url from a paperclip'd object, use the image_path helper; this is what image_tag uses to generate the url for an img tag.
These two comments seem in conflict with each other (to me). If Paperclip can use the asset_host settings, it seems almost necessary that it would generate the full url (since the asset_host only specifies the start (host) of that url)
But it then goes on to say you need to use a helper to get the full url??
The reason I ask this is because I want full urls generated for image url serialization (ie if we're returning json with image_urls, we want those served from our CDN).
Right now I've created a helper module that extends extend ::Sprockets::Helpers::RailsHelper to manually generate full urls any time an image_url is being serialized, but it's manual (and someone could possibly forget to do it in the future)
Any thoughts?
I'm trying to i18n the image_uid attribute in my model so I can have different images with different languages. I'm using globalize3 and dragonfly.
The problem is that is not working at all. It usually uploads the spanish image (which is the default locale in my app), but it doesn't work with other locales. I don't get any error or trace, it just doesn't work.
The model is quite simple:
image_accessor :image
translates :image_uid
Any idea?
:image_uid is the uniqe id to identify the image and therefore not suitable for translation. But if a :image_name attribute is present Dragonfly uses that as filename.
If you want to have a different image for every language because you e.g insert text, you have to watch out that the name or more precisely the url is always different, e.g. you could append the locale to the url: ?locale=en, or name your files translation.en.jpg. To assign the name you can use the helper methods #model.image.name, .basename, and .ext.
If you want only the filename to change and always have the same image served you need a url rewrite engine and remove the filename before your cache. Otherwise unneeded copies of the same image would be created and waste your disk space and processing power.
Using the rack-rewrite and rack-cache gems it would look something like that:
require 'dragonfly/rails/images'
Rails.application.middleware.insert_before(Rack::Cache, Rack::Rewrite) do
rewrite %r{/media/([^/]+)/[^?]*(.*)}, '/media/$1$2'
end
<img alt="Phone_large" src="/system/photos/1/small/phone_large.jpg?1238845838" />
Why is "?1238845838" added to the image path?
How can I get my path/url without it?
It's commonly referred to as a "cache buster". Paperclip automatically appends the timestamp for the last time the file was updated.
Say you were to remove the cache buster and use /system/photos/1/small/phone_large.jpg instead. The URL wouldn't change when you changed the image and your visitors would see the old image for as long as they had it cached.
If you want to remove it just call .url(:default, timestamp: false). Of course you can change :default to any other style you've defined.
Or if you want to globally default them to off, just put this in a config/initializers/paperclip.rb file.
Paperclip::Attachment.default_options[:use_timestamp] = false