Repository: rails/rails
File: activestorage/app/models/active_storage/attachment.rb (Ruby)

Code before:

  private
    def analyze_blob_later
      blob.analyze_later unless blob.analyzed?
    end

    def mirror_blob_later
      blob.mirror_later
    end

    def create_variants
      return unless representable?

      immediate_transformations = []
      later_transformations     = []

      named_variants.each do |_name, named_variant|
        case named_variant.process(record)
        when :immediately
          immediate_transformations << named_variant.transformations
        when :later
          later_transformations << named_variant.transformations
        end
      end

      ActiveStorage::CreateVariantsJob.perform_now(blob, transformations: immediate_transformations, process: :immediately) if immediate_transformations.any?
      ActiveStorage::CreateVariantsJob.perform_later(blob, transformations: later_transformations, process: :later) if later_transformations.any?
    end

    def purge_dependent_blob_later
      blob&.purge_later if dependent == :purge_later
    end

    def dependent
      record.attachment_reflections[name]&.options&.fetch(:dependent, nil)
    end

    def named_variants
      record.attachment_reflections[name]&.named_variants || {}
    end

    def transformations_by_name(transformations)
      case transformations
      when Symbol
        variant_name = transformations
        named_variants.fetch(variant_name) do
          record_model_name = record.to_model.model_name.name
          raise ArgumentError, "Cannot find variant :#{variant_name} for #{record_model_name}##{name}"
        end.transformations
      else
        transformations

Review comment (performance):
If these are always created immediately, should we just inline the logic here and remove some complexity from `ActiveStorage::CreateVariantsJob`?
No one should ever call the following by accident I think:
```ruby
ActiveStorage::CreateVariantsJob.perform_later(
  blob,
  transformations: immediate_transformations,
  process: :later)
```

Code after:

  private
    def analyze_blob_later
      blob.analyze_later unless blob.analyzed?
    end

    def mirror_blob_later
      blob.mirror_later
    end

    def create_variants
      return unless representable?

      immediate_variants = []
      later_variants     = []

      named_variants.each do |_name, named_variant|
        case named_variant.process(record)
        when :immediately
          immediate_variants << named_variant.transformations
        when :later
          later_variants << named_variant.transformations
        end
      end

      ActiveStorage::CreateVariantsJob.perform_now(blob, variants: immediate_variants, process: :immediately) if immediate_variants.any?
      ActiveStorage::CreateVariantsJob.perform_later(blob, variants: later_variants, process: :later) if later_variants.any?
    end

    def purge_dependent_blob_later
      blob&.purge_later if dependent == :purge_later
    end

    def dependent
      record.attachment_reflections[name]&.options&.fetch(:dependent, nil)
    end

    def named_variants
      record.attachment_reflections[name]&.named_variants || {}
    end

    def transformations_by_name(transformations)
      case transformations
      when Symbol
        variant_name = transformations
        named_variants.fetch(variant_name) do
          record_model_name = record.to_model.model_name.name
          raise ArgumentError, "Cannot find variant :#{variant_name} for #{record_model_name}##{name}"
        end.transformations
      else
        transformations