Default transformations for ActiveStorage attachments
Declare default transformations for ActiveStorage attachments
Recently I needed to crop images across a variety of models and attachments on a recent Rails project using ActiveStorage.
The initial native solution was to implement methods in each of these models, check to see if there are any stored crop settings, and perform cropping and any extra passed in image transformations to variant
. This quickly bloated out off control.
To combat this the following monkey-patch was implemented to apply default transformations to variant
calls across the project. Right now it only handles the needed image cropping but would be easily extendable to a variety of other situations (e.g. checking for and calling a default_name_transformations
method on the record and merging that into the provided variant transformations).
The monkey-patch to support image cropping looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
module ActiveStorage
class Attached
CROP_SETTINGS_SUFFIX = "_crop_settings".freeze
def variant(transformations)
attachment.public_send(:variant, default_transformations.merge(transformations))
end
private
def default_transformations
{
crop: crop_transformation
}.compact
end
def crop_transformation
attachment_crop_settings_attribute = "#{name}#{CROP_SETTINGS_SUFFIX}"
return unless record.respond_to?(attachment_crop_settings_attribute)
if (crop_settings = record.send(attachment_crop_settings_attribute)).present?
w, h, x, y = crop_settings.values_at("w", "h", "x", "y")
"#{w}x#{h}+#{x}+#{y}"
end
end
end
end
1
2
3
4
5
6
7
8
9
module TestApp
class Application < Rails::Application
# ...
config.to_prepare do
require 'ext/active_storage/attached'
end
end
end