Paperclip Rails url and asset_host - ruby-on-rails

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?

Related

Rails: Permanent url for active storage videos

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)

What is the purpose of using rails' image_url helper?

From the docs it seems like you just save yourself from typing in the assets folder part of the image url when using this method against the vanilla url helper? What is the usefulness of this?
When you use image_url helper then rails will map the full qualified url based on the asset_host configuration. So this method gives you the freedom of just passing the name of the image as an argument and it does the rest.
Check this for more information.
http://api.rubyonrails.org/classes/ActionView/Helpers/AssetUrlHelper.html

Get ASP.NET bundle URL for use with CDN?

I'm using the ASP.NET bundling feature and want to know how I can get the URL returned by the Render helpers such as Scripts.Render("~/bundles/scripts").
Currently the optimized output is has a relative URL. I want to use a CDN that does origin-caching, so the final URL needs to be something like http://static.mydomain.com/bundles/scripts?v=XXXXXX
My plan is to simply write my own helper method, but I can't figure out how to get the version number relative URL for a given bundle.
The solution was rather simple. There is a static method Scripts.Url and Styles.Url that give me exactly what I want. I was able to incorporate this into my own helper to concatenate the CDN's base URL.

Using dragonfly with globalize

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

Browser Caching with Paperclip

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.

Resources