Skip to content

Instantly share code, notes, and snippets.

@fabiode
Created January 18, 2022 17:52
Show Gist options
  • Save fabiode/f79faf59e27a0d07d5e60c7e91b3bcc6 to your computer and use it in GitHub Desktop.
Save fabiode/f79faf59e27a0d07d5e60c7e91b3bcc6 to your computer and use it in GitHub Desktop.
Adding a concern for image size variants for ActiveStorage, similar on how paperclip gem used to do
### Example of Use
class User < ApplicationRecord
include ImageVariants
has_one_attached :avatar
image_variants_for :avatar, sizes: { custom_size: }, default_image: '/path/to/default/image'
end
require 'active_support/concern'
module ImageVariants
extend ActiveSupport::Concern
class_methods do
attr_reader :_attachment_name, :_image_sizes, :_default_image
def image_variants_for(name, sizes: _default_sizes, default_image: _image)
@_attachment_name = name
@_image_sizes = sizes
@_default_image = default_image
end
def _default_sizes
{
avatar: { combine_options: { resize: '80x80^', extent: '80x80', gravity: 'Center' } },
thumb: { combine_options: { resize: '256x256^', crop: '128x128+0-10', gravity: 'Center' } },
card: { combine_options: { resize: '640x360^', crop: '640x360+0+0', gravity: 'Center' } },
cover: { combine_options: { resize: '1280x720^', crop: '1280x720+0+0', gravity: 'Center' } }
}
end
def _image
'/default.png'
end
end
included do
after_initialize do
define_singleton_method("#{self.class._attachment_name}_image") do |size = nil|
_attachment.attached? ? variant_image(size) : self.class._default_image
end
end
end
private
def image_variants(size)
self.class._image_sizes[size.to_sym]
end
def _attachment
public_send(self.class._attachment_name)
end
def variant_image(size)
size = image_variants(size)
if size && _attachment.blob.variable?
variant = _attachment.variant(size)
variant.processed.service_url
else
_attachment.service_url
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment