Last active
October 17, 2022 15:34
-
-
Save brenogazzola/9f6c0c307f1a00c260a0818557dc3587 to your computer and use it in GitHub Desktop.
Creating a custom ActiveStorage controller to generate "pretty urls" or help migration from another lib
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This demonstrates how we create a SEO friendly url for the previews of the artworks we sell. | |
# | |
# This is the URL we want: | |
# https://festalab.com.br/image/invitation/birthday/carnival.jpg | |
# | |
# First, the route. | |
# | |
# "model" is the name of the active storage model that has the preview. | |
# "classification" and "identifier" are together a unique key for the records. | |
Rails.application.routes.draw do | |
get "image/:model/:classification/:identifier", to: "imager/previews#show", as: :imager_preview | |
# model : invitation | |
# classification: birthday | |
# identifier : carnival | |
end | |
# Here's the custom controller. This is based on Rails 7.0, so you might have to change | |
# which controller you inherit from in previous Rails versions. | |
# | |
class Imager::PreviewsController < ActiveStorage::BaseController | |
include Imager::SetBlob | |
include Imager::SetVariationKey | |
def show | |
http_cache_forever public: true do | |
send_blob_stream representation.image | |
end | |
rescue => error | |
logger.error(error) if Rails.env.production? | |
head :unprocessable_entity | |
end | |
private | |
def representation | |
@representation ||= @blob.representation(@variation_key).processed | |
end | |
end | |
# This is the SetBlob concern. Instead of using the default signed_id param that active storage uses, we use our | |
# own parameters to locate the blob. | |
module Imager::SetBlob #:nodoc: | |
extend ActiveSupport::Concern | |
included do | |
before_action :set_blob | |
end | |
private | |
def set_blob | |
model = params[:model].constantize | |
classification = params[:classification] | |
identifier = params[:identifier] | |
@blob = model.find_by(classification: classification, identifier: identifier).preview.blob | |
rescue => error | |
logger.error(error) if Rails.env.production? | |
head :not_found | |
end | |
end | |
# This is the SetVariation concern. Instead of using the default variation_key param, we define our own transformations | |
# frozen_string_literal: true | |
module Imager::SetVariationKey #:nodoc: | |
extend ActiveSupport::Concern | |
included do | |
before_action :set_variation_key | |
end | |
private | |
def set_variation_key | |
@variation_key = ActiveStorage::Variation.new(transformations) | |
rescue => error | |
logger.error(error) if Rails.env.production? | |
head :not_acceptable | |
end | |
def transformations | |
{ format: :jpg, saver: {strip: true, quality: 80 }} | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks!
I've chosen to
include ActiveStorage::Streaming
instead of extendingActiveStorage::BaseController