'Rails Active Storage: How to create "named variants" that are cropped by user-supplied coordinates

I have something like:

class User < ApplicationRecord

  has_one_attached :avatar do |attachable|
    attachable.variant :large,  resize_to_limit: [300, nil]
    attachable.variant :medium, resize_to_limit: [100, nil]
    attachable.variant :small,  resize_to_limit: [ 50, nil]
  end

end

How do I create...

  • such "named variants"
  • that are (first) cropped by user-supplied coordinates such as: [x, y, width, height]
  • while keeping the uploaded (original) file unchanged?

Is it possible to "pass the coordinates to the model" somehow? If yes, how?

If not: Would the cropping need to happen separately in a controller action, creating a cropped version (of the original file), based upon which the "named variants" would be created? If so, how would that look?



Solution 1:[1]

I'll try to answer your question:

  1. I don't tink you can pass params to variant that way as definition is in model. You can generate the variant in a method (in the controller - in a before/after save/create filter) or in a view using: user.avatar.variant(:large). If done in the view append .processed to retrieve the already generated variant if present.
  2. To crop and resize add: resize_to_limit: [300, 100], crop: '200x300+0+0'

If you want to get dimensions and coordinates from params then i would not use named variant, but something like

In model: has_one_attached :avatar

In controller:

def image_height
  params[:height]
end

def generate_variant_small
  @user.avatar.variant(resize_to_limit: "300x#{image_height}^", crop: '200x300+0+0').processed
end
  1. Original image will be untouched. You upload original image, then all variants will be processed as new images.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Joe