Skip to content

Instantly share code, notes, and snippets.

@cleicar
Created August 4, 2020 20:56
Show Gist options
  • Save cleicar/a08114ebc155582ab4a329453ee005c4 to your computer and use it in GitHub Desktop.
Save cleicar/a08114ebc155582ab4a329453ee005c4 to your computer and use it in GitHub Desktop.
Active Storage Key
# config/initializers/activestorage_extensions.rb
# frozen_string_literal: true
module NitroAttached
def service_url
# url: user.avatar.url,
# filename: filename
end
def short_expiring_url(_time = 3600, style_name = :medium)
if attachment.record.avatar_file_name.present?
url(style_name) # PAPERCLIP
else
main_app.url_for(attachment.record) # ACTIVE STORAGE
end
end
def url(style_name = default_style, options = {})
if options.include?([true, false]) # Backwards compatibility.
url_generator_for(style_name, default_options.merge(timestamp: options))
else
url_generator_for(style_name, default_options.merge(options))
end
end
def url_generator_for(style_name, options)
interpolated = "avatars/#{attachment.record.id}/#{style_name}/#{attachment.record.avatar_file_name}?"
escaped = escape_url_as_needed(interpolated, options)
timestamp_as_needed(escaped, options)
end
def timestamp_as_needed(url, options)
if options[:timestamp] && timestamp_possible?
delimiter_char = /\?.+=/.match?(url) ? "&" : "?"
"#{url}#{delimiter_char}#{@attachment.updated_at}"
else
url
end
end
def timestamp_possible?
@attachment.respond_to?(:updated_at) && @attachment.updated_at.present?
end
def interpolate(pattern, *args)
pattern = args.first.instance.send(pattern) if pattern.is_a? Symbol
result = pattern.dup
interpolators_cache.each do |method, token|
result.gsub!(token) { send(method, *args) } if result.include?(token)
end
# /:attachment/:id/:style/:filename
# /avatars/11242/medium/Ryan_Alde.JPG?AWSAccessKeyId=GWNQSVNDS
# &Signature=JgeIJ1%2Bpz9ZkOQQK7Ms3/MianCc%3D&Expires=3191749244
result
end
def filename(attachment, style_name)
[basename(attachment, style_name), extension(attachment, style_name)].delete_if(&:empty?).join(".")
end
def interpolators_cache
@interpolators_cache ||= interpolators_list.reverse!.map! { |method| [method, ":#{method}"] }
end
def interpolators_list
%i[
attachment
id
filename
style
]
end
def most_appropriate_url
return default_url if attachment.blank?
if attachment.record.avatar_file_name.nil?
default_url
else
default_options[:url]
end
end
def default_url
"/avatars/medium/missing.png"
end
def default_options
{
url: ":attachment/:id/:style/:filename",
}
end
def attachment_options
{}
end
def escape_url_as_needed(url, options)
if options[:escape]
escape_url(url)
else
url
end
end
def escape_url(url)
if url.respond_to?(:escape)
url.escape
else
CGI.escape(url).gsub(escape_regex) { |m| "%#{m.ord.to_s(16).upcase}" }
end
end
end
module NitroAttachment
extend ActiveSupport::Concern
included do
self.table_name = "core_models_active_storage_attachments"
end
end
module NitroVariant
extend ActiveSupport::Concern
# Returns a combination key of the blob and the variation that together identifies a specific variant.
def key
"avatars/#{self.blob.attachments.first.record.id}/medium/#{self.blob.filename.to_s}"
end
end
::ActiveStorage::Attachment.include NitroAttachment
::ActiveStorage::Attached::One.include NitroAttached
::ActiveStorage::Variant.include NitroVariant
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment