activestorage 7.2.2.2 → 7.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -1
- data/README.md +1 -1
- data/app/controllers/active_storage/disk_controller.rb +2 -2
- data/app/models/active_storage/blob/representable.rb +66 -0
- data/app/models/active_storage/blob.rb +1 -17
- data/lib/active_storage/attached/changes/create_one.rb +1 -1
- data/lib/active_storage/attached/model.rb +21 -2
- data/lib/active_storage/engine.rb +4 -1
- data/lib/active_storage/fixture_set.rb +1 -1
- data/lib/active_storage/gem_version.rb +2 -2
- data/lib/active_storage/service/s3_service.rb +19 -4
- metadata +12 -12
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 94213ce5408fd1a4c67c6bf4854d2f2c55289813ef0297dfc33fb3325ec5dfd4
         | 
| 4 | 
            +
              data.tar.gz: 73de432409f6bb50456de14131e01c649b0172fcd5c0d5178b61b385cc236e37
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 48271c643e3a2a6ffbabdc398863f9452d3cdc2c01540b94a28f512fcc828d1792d13fd36ec05c890e3b02dc7d6fc33439c792eebbda2ab720479032307c947a
         | 
| 7 | 
            +
              data.tar.gz: 65acfc493d0aa029d4b533dd086cdeb9e35c04c6b4b4b6ee678101516bfc9428ffc477be92d5d49c5c1f6f43f6bed29b2c7ccbacf11f650e27fae34a779bb672
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,11 +1,31 @@ | |
| 1 | 
            +
            ## Rails 7.2.3 (October 28, 2025) ##
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            *   Fix `config.active_storage.touch_attachment_records` to work with eager loading.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                *fatkodima*
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            *   A Blob will no longer autosave associated Attachment.
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                This fixes an issue where a record with an attachment would have
         | 
| 10 | 
            +
                its dirty attributes reset, preventing your `after commit` callbacks
         | 
| 11 | 
            +
                on that record to behave as expected.
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                Note that this change doesn't require any changes on your application
         | 
| 14 | 
            +
                and is supposed to be internal. Active Storage Attachment will continue
         | 
| 15 | 
            +
                to be autosaved (through a different relation).
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                *Edouard-chin*
         | 
| 18 | 
            +
             | 
| 19 | 
            +
             | 
| 1 20 | 
             
            ## Rails 7.2.2.2 (August 13, 2025) ##
         | 
| 2 21 |  | 
| 3 | 
            -
             | 
| 22 | 
            +
            *   Remove dangerous transformations
         | 
| 4 23 |  | 
| 5 24 | 
             
                [CVE-2025-24293]
         | 
| 6 25 |  | 
| 7 26 | 
             
                *Zack Deveau*
         | 
| 8 27 |  | 
| 28 | 
            +
             | 
| 9 29 | 
             
            ## Rails 7.2.2.1 (December 10, 2024) ##
         | 
| 10 30 |  | 
| 11 31 | 
             
            *   No changes.
         | 
    
        data/README.md
    CHANGED
    
    | @@ -203,6 +203,6 @@ Bug reports for the Ruby on \Rails project can be filed here: | |
| 203 203 |  | 
| 204 204 | 
             
            * https://github.com/rails/rails/issues
         | 
| 205 205 |  | 
| 206 | 
            -
            Feature requests should be discussed on the  | 
| 206 | 
            +
            Feature requests should be discussed on the rubyonrails-core forum here:
         | 
| 207 207 |  | 
| 208 208 | 
             
            * https://discuss.rubyonrails.org/c/rubyonrails-core
         | 
| @@ -25,13 +25,13 @@ class ActiveStorage::DiskController < ActiveStorage::BaseController | |
| 25 25 | 
             
                    named_disk_service(token[:service_name]).upload token[:key], request.body, checksum: token[:checksum]
         | 
| 26 26 | 
             
                    head :no_content
         | 
| 27 27 | 
             
                  else
         | 
| 28 | 
            -
                    head  | 
| 28 | 
            +
                    head ActionDispatch::Constants::UNPROCESSABLE_CONTENT
         | 
| 29 29 | 
             
                  end
         | 
| 30 30 | 
             
                else
         | 
| 31 31 | 
             
                  head :not_found
         | 
| 32 32 | 
             
                end
         | 
| 33 33 | 
             
              rescue ActiveStorage::IntegrityError
         | 
| 34 | 
            -
                head  | 
| 34 | 
            +
                head ActionDispatch::Constants::UNPROCESSABLE_CONTENT
         | 
| 35 35 | 
             
              end
         | 
| 36 36 |  | 
| 37 37 | 
             
              private
         | 
| @@ -31,6 +31,72 @@ module ActiveStorage::Blob::Representable | |
| 31 31 | 
             
              # Raises ActiveStorage::InvariableError if the variant processor cannot
         | 
| 32 32 | 
             
              # transform the blob. To determine whether a blob is variable, call
         | 
| 33 33 | 
             
              # ActiveStorage::Blob#variable?.
         | 
| 34 | 
            +
              #
         | 
| 35 | 
            +
              # ==== Options
         | 
| 36 | 
            +
              #
         | 
| 37 | 
            +
              # Options are defined by the {image_processing gem}[https://github.com/janko/image_processing],
         | 
| 38 | 
            +
              # and depend on which variant processor you are using:
         | 
| 39 | 
            +
              # {Vips}[https://github.com/janko/image_processing/blob/master/doc/vips.md] or
         | 
| 40 | 
            +
              # {MiniMagick}[https://github.com/janko/image_processing/blob/master/doc/minimagick.md].
         | 
| 41 | 
            +
              # However, both variant processors support the following options:
         | 
| 42 | 
            +
              #
         | 
| 43 | 
            +
              # [+:resize_to_limit+]
         | 
| 44 | 
            +
              #   Downsizes the image to fit within the specified dimensions while retaining
         | 
| 45 | 
            +
              #   the original aspect ratio. Will only resize the image if it's larger than
         | 
| 46 | 
            +
              #   the specified dimensions.
         | 
| 47 | 
            +
              #
         | 
| 48 | 
            +
              #       user.avatar.variant(resize_to_limit: [100, 100])
         | 
| 49 | 
            +
              #
         | 
| 50 | 
            +
              # [+:resize_to_fit+]
         | 
| 51 | 
            +
              #   Resizes the image to fit within the specified dimensions while retaining
         | 
| 52 | 
            +
              #   the original aspect ratio. Will downsize the image if it's larger than the
         | 
| 53 | 
            +
              #   specified dimensions or upsize if it's smaller.
         | 
| 54 | 
            +
              #
         | 
| 55 | 
            +
              #       user.avatar.variant(resize_to_fit: [100, 100])
         | 
| 56 | 
            +
              #
         | 
| 57 | 
            +
              # [+:resize_to_fill+]
         | 
| 58 | 
            +
              #   Resizes the image to fill the specified dimensions while retaining the
         | 
| 59 | 
            +
              #   original aspect ratio. If necessary, will crop the image in the larger
         | 
| 60 | 
            +
              #   dimension.
         | 
| 61 | 
            +
              #
         | 
| 62 | 
            +
              #       user.avatar.variant(resize_to_fill: [100, 100])
         | 
| 63 | 
            +
              #
         | 
| 64 | 
            +
              # [+:resize_and_pad+]
         | 
| 65 | 
            +
              #   Resizes the image to fit within the specified dimensions while retaining
         | 
| 66 | 
            +
              #   the original aspect ratio. If necessary, will pad the remaining area with
         | 
| 67 | 
            +
              #   transparent color if source image has alpha channel, black otherwise.
         | 
| 68 | 
            +
              #
         | 
| 69 | 
            +
              #       user.avatar.variant(resize_and_pad: [100, 100])
         | 
| 70 | 
            +
              #
         | 
| 71 | 
            +
              # [+:crop+]
         | 
| 72 | 
            +
              #   Extracts an area from an image. The first two arguments are the left and
         | 
| 73 | 
            +
              #   top edges of area to extract, while the last two arguments are the width
         | 
| 74 | 
            +
              #   and height of the area to extract.
         | 
| 75 | 
            +
              #
         | 
| 76 | 
            +
              #       user.avatar.variant(crop: [20, 50, 300, 300])
         | 
| 77 | 
            +
              #
         | 
| 78 | 
            +
              # [+:rotate+]
         | 
| 79 | 
            +
              #   Rotates the image by the specified angle.
         | 
| 80 | 
            +
              #
         | 
| 81 | 
            +
              #       user.avatar.variant(rotate: 90)
         | 
| 82 | 
            +
              #
         | 
| 83 | 
            +
              # Some options, including those listed above, can accept additional
         | 
| 84 | 
            +
              # processor-specific values which can be passed as a trailing hash:
         | 
| 85 | 
            +
              #
         | 
| 86 | 
            +
              #     <!-- Vips supports configuring `crop` for many of its transformations -->
         | 
| 87 | 
            +
              #     <%= image_tag user.avatar.variant(resize_to_fill: [100, 100, { crop: :centre }]) %>
         | 
| 88 | 
            +
              #
         | 
| 89 | 
            +
              # If migrating an existing application between MiniMagick and Vips, you will
         | 
| 90 | 
            +
              # need to update processor-specific options:
         | 
| 91 | 
            +
              #
         | 
| 92 | 
            +
              #     <!-- MiniMagick -->
         | 
| 93 | 
            +
              #     <%= image_tag user.avatar.variant(resize_to_limit: [100, 100], format: :jpeg,
         | 
| 94 | 
            +
              #           sampling_factor: "4:2:0", strip: true, interlace: "JPEG", colorspace: "sRGB", quality: 80) %>
         | 
| 95 | 
            +
              #
         | 
| 96 | 
            +
              #     <!-- Vips -->
         | 
| 97 | 
            +
              #     <%= image_tag user.avatar.variant(resize_to_limit: [100, 100], format: :jpeg,
         | 
| 98 | 
            +
              #           saver: { subsample_mode: "on", strip: true, interlace: true, quality: 80 }) %>
         | 
| 99 | 
            +
              #
         | 
| 34 100 | 
             
              def variant(transformations)
         | 
| 35 101 | 
             
                if variable?
         | 
| 36 102 | 
             
                  variant_class.new(self, ActiveStorage::Variation.wrap(transformations).default_to(default_variant_transformations))
         | 
| @@ -29,7 +29,7 @@ class ActiveStorage::Blob < ActiveStorage::Record | |
| 29 29 | 
             
              # :method:
         | 
| 30 30 | 
             
              #
         | 
| 31 31 | 
             
              # Returns the associated ActiveStorage::Attachment instances.
         | 
| 32 | 
            -
              has_many :attachments
         | 
| 32 | 
            +
              has_many :attachments, autosave: false
         | 
| 33 33 |  | 
| 34 34 | 
             
              ##
         | 
| 35 35 | 
             
              # :singleton-method:
         | 
| @@ -152,22 +152,6 @@ class ActiveStorage::Blob < ActiveStorage::Record | |
| 152 152 | 
             
                    combined_blob.save!
         | 
| 153 153 | 
             
                  end
         | 
| 154 154 | 
             
                end
         | 
| 155 | 
            -
             | 
| 156 | 
            -
                def validate_service_configuration(service_name, model_class, association_name) # :nodoc:
         | 
| 157 | 
            -
                  if service_name
         | 
| 158 | 
            -
                    services.fetch(service_name) do
         | 
| 159 | 
            -
                      raise ArgumentError, "Cannot configure service #{service_name.inspect} for #{model_class}##{association_name}"
         | 
| 160 | 
            -
                    end
         | 
| 161 | 
            -
                  else
         | 
| 162 | 
            -
                    validate_global_service_configuration
         | 
| 163 | 
            -
                  end
         | 
| 164 | 
            -
                end
         | 
| 165 | 
            -
             | 
| 166 | 
            -
                def validate_global_service_configuration # :nodoc:
         | 
| 167 | 
            -
                  if connected? && table_exists? && Rails.configuration.active_storage.service.nil?
         | 
| 168 | 
            -
                    raise RuntimeError, "Missing Active Storage service name. Specify Active Storage service name for config.active_storage.service in config/environments/#{Rails.env}.rb"
         | 
| 169 | 
            -
                  end
         | 
| 170 | 
            -
                end
         | 
| 171 155 | 
             
              end
         | 
| 172 156 |  | 
| 173 157 | 
             
              include Analyzable
         | 
| @@ -121,7 +121,7 @@ module ActiveStorage | |
| 121 121 | 
             
                    service_name = record.attachment_reflections[name].options[:service_name]
         | 
| 122 122 | 
             
                    if service_name.is_a?(Proc)
         | 
| 123 123 | 
             
                      service_name = service_name.call(record)
         | 
| 124 | 
            -
                       | 
| 124 | 
            +
                      Attached::Model.validate_service_configuration(service_name, record.class, name)
         | 
| 125 125 | 
             
                    end
         | 
| 126 126 | 
             
                    service_name
         | 
| 127 127 | 
             
                  end
         | 
| @@ -104,7 +104,7 @@ module ActiveStorage | |
| 104 104 | 
             
                  # <tt>active_storage_attachments.record_type</tt> polymorphic type column of
         | 
| 105 105 | 
             
                  # the corresponding rows.
         | 
| 106 106 | 
             
                  def has_one_attached(name, dependent: :purge_later, service: nil, strict_loading: false)
         | 
| 107 | 
            -
                     | 
| 107 | 
            +
                    Attached::Model.validate_service_configuration(service, self, name) unless service.is_a?(Proc)
         | 
| 108 108 |  | 
| 109 109 | 
             
                    generated_association_methods.class_eval <<-CODE, __FILE__, __LINE__ + 1
         | 
| 110 110 | 
             
                      # frozen_string_literal: true
         | 
| @@ -204,7 +204,7 @@ module ActiveStorage | |
| 204 204 | 
             
                  # <tt>active_storage_attachments.record_type</tt> polymorphic type column of
         | 
| 205 205 | 
             
                  # the corresponding rows.
         | 
| 206 206 | 
             
                  def has_many_attached(name, dependent: :purge_later, service: nil, strict_loading: false)
         | 
| 207 | 
            -
                     | 
| 207 | 
            +
                    Attached::Model.validate_service_configuration(service, self, name) unless service.is_a?(Proc)
         | 
| 208 208 |  | 
| 209 209 | 
             
                    generated_association_methods.class_eval <<-CODE, __FILE__, __LINE__ + 1
         | 
| 210 210 | 
             
                      # frozen_string_literal: true
         | 
| @@ -255,6 +255,25 @@ module ActiveStorage | |
| 255 255 | 
             
                  end
         | 
| 256 256 | 
             
                end
         | 
| 257 257 |  | 
| 258 | 
            +
                class << self
         | 
| 259 | 
            +
                  def validate_service_configuration(service_name, model_class, association_name) # :nodoc:
         | 
| 260 | 
            +
                    if service_name
         | 
| 261 | 
            +
                      ActiveStorage::Blob.services.fetch(service_name) do
         | 
| 262 | 
            +
                        raise ArgumentError, "Cannot configure service #{service_name.inspect} for #{model_class}##{association_name}"
         | 
| 263 | 
            +
                      end
         | 
| 264 | 
            +
                    else
         | 
| 265 | 
            +
                      validate_global_service_configuration(model_class)
         | 
| 266 | 
            +
                    end
         | 
| 267 | 
            +
                  end
         | 
| 268 | 
            +
             | 
| 269 | 
            +
                  private
         | 
| 270 | 
            +
                    def validate_global_service_configuration(model_class)
         | 
| 271 | 
            +
                      if model_class.connected? && ActiveStorage::Blob.table_exists? && Rails.configuration.active_storage.service.nil?
         | 
| 272 | 
            +
                        raise RuntimeError, "Missing Active Storage service name. Specify Active Storage service name for config.active_storage.service in config/environments/#{Rails.env}.rb"
         | 
| 273 | 
            +
                      end
         | 
| 274 | 
            +
                    end
         | 
| 275 | 
            +
                end
         | 
| 276 | 
            +
             | 
| 258 277 | 
             
                def attachment_changes # :nodoc:
         | 
| 259 278 | 
             
                  @attachment_changes ||= {}
         | 
| 260 279 | 
             
                end
         | 
| @@ -84,6 +84,10 @@ module ActiveStorage | |
| 84 84 | 
             
                end
         | 
| 85 85 |  | 
| 86 86 | 
             
                initializer "active_storage.configs" do
         | 
| 87 | 
            +
                  config.before_initialize do |app|
         | 
| 88 | 
            +
                    ActiveStorage.touch_attachment_records = app.config.active_storage.touch_attachment_records != false
         | 
| 89 | 
            +
                  end
         | 
| 90 | 
            +
             | 
| 87 91 | 
             
                  config.after_initialize do |app|
         | 
| 88 92 | 
             
                    ActiveStorage.logger            = app.config.active_storage.logger || Rails.logger
         | 
| 89 93 | 
             
                    ActiveStorage.variant_processor = app.config.active_storage.variant_processor || :mini_magick
         | 
| @@ -112,7 +116,6 @@ module ActiveStorage | |
| 112 116 | 
             
                    ActiveStorage.variable_content_types = app.config.active_storage.variable_content_types || []
         | 
| 113 117 | 
             
                    ActiveStorage.web_image_content_types = app.config.active_storage.web_image_content_types || []
         | 
| 114 118 | 
             
                    ActiveStorage.content_types_to_serve_as_binary = app.config.active_storage.content_types_to_serve_as_binary || []
         | 
| 115 | 
            -
                    ActiveStorage.touch_attachment_records = app.config.active_storage.touch_attachment_records != false
         | 
| 116 119 | 
             
                    ActiveStorage.service_urls_expire_in = app.config.active_storage.service_urls_expire_in || 5.minutes
         | 
| 117 120 | 
             
                    ActiveStorage.urls_expire_in = app.config.active_storage.urls_expire_in
         | 
| 118 121 | 
             
                    ActiveStorage.content_types_allowed_inline = app.config.active_storage.content_types_allowed_inline || []
         | 
| @@ -50,7 +50,7 @@ module ActiveStorage | |
| 50 50 | 
             
                # by ActiveSupport::Testing::FileFixtures.file_fixture, and upload
         | 
| 51 51 | 
             
                # the file to the Service
         | 
| 52 52 | 
             
                #
         | 
| 53 | 
            -
                #  | 
| 53 | 
            +
                # ==== Examples
         | 
| 54 54 | 
             
                #
         | 
| 55 55 | 
             
                #   # tests/fixtures/active_storage/blobs.yml
         | 
| 56 56 | 
             
                #   second_thumbnail_blob: <%= ActiveStorage::FixtureSet.blob(
         | 
| @@ -16,6 +16,7 @@ module ActiveStorage | |
| 16 16 |  | 
| 17 17 | 
             
                def initialize(bucket:, upload: {}, public: false, **options)
         | 
| 18 18 | 
             
                  @client = Aws::S3::Resource.new(**options)
         | 
| 19 | 
            +
                  @transfer_manager = Aws::S3::TransferManager.new(client: @client.client) if defined?(Aws::S3::TransferManager)
         | 
| 19 20 | 
             
                  @bucket = @client.bucket(bucket)
         | 
| 20 21 |  | 
| 21 22 | 
             
                  @multipart_upload_threshold = upload.delete(:multipart_threshold) || 100.megabytes
         | 
| @@ -100,7 +101,8 @@ module ActiveStorage | |
| 100 101 | 
             
                def compose(source_keys, destination_key, filename: nil, content_type: nil, disposition: nil, custom_metadata: {})
         | 
| 101 102 | 
             
                  content_disposition = content_disposition_with(type: disposition, filename: filename) if disposition && filename
         | 
| 102 103 |  | 
| 103 | 
            -
                   | 
| 104 | 
            +
                  upload_stream(
         | 
| 105 | 
            +
                    key: destination_key,
         | 
| 104 106 | 
             
                    content_type: content_type,
         | 
| 105 107 | 
             
                    content_disposition: content_disposition,
         | 
| 106 108 | 
             
                    part_size: MINIMUM_UPLOAD_PART_SIZE,
         | 
| @@ -116,6 +118,14 @@ module ActiveStorage | |
| 116 118 | 
             
                end
         | 
| 117 119 |  | 
| 118 120 | 
             
                private
         | 
| 121 | 
            +
                  def upload_stream(key:, **options, &block)
         | 
| 122 | 
            +
                    if @transfer_manager
         | 
| 123 | 
            +
                      @transfer_manager.upload_stream(key: key, bucket: bucket.name, **options, &block)
         | 
| 124 | 
            +
                    else
         | 
| 125 | 
            +
                      object_for(key).upload_stream(**options, &block)
         | 
| 126 | 
            +
                    end
         | 
| 127 | 
            +
                  end
         | 
| 128 | 
            +
             | 
| 119 129 | 
             
                  def private_url(key, expires_in:, filename:, disposition:, content_type:, **client_opts)
         | 
| 120 130 | 
             
                    object_for(key).presigned_url :get, expires_in: expires_in.to_i,
         | 
| 121 131 | 
             
                      response_content_disposition: content_disposition_with(type: disposition, filename: filename),
         | 
| @@ -126,7 +136,6 @@ module ActiveStorage | |
| 126 136 | 
             
                    object_for(key).public_url(**client_opts)
         | 
| 127 137 | 
             
                  end
         | 
| 128 138 |  | 
| 129 | 
            -
             | 
| 130 139 | 
             
                  MAXIMUM_UPLOAD_PARTS_COUNT = 10000
         | 
| 131 140 | 
             
                  MINIMUM_UPLOAD_PART_SIZE   = 5.megabytes
         | 
| 132 141 |  | 
| @@ -139,12 +148,18 @@ module ActiveStorage | |
| 139 148 | 
             
                  def upload_with_multipart(key, io, content_type: nil, content_disposition: nil, custom_metadata: {})
         | 
| 140 149 | 
             
                    part_size = [ io.size.fdiv(MAXIMUM_UPLOAD_PARTS_COUNT).ceil, MINIMUM_UPLOAD_PART_SIZE ].max
         | 
| 141 150 |  | 
| 142 | 
            -
                     | 
| 151 | 
            +
                    upload_stream(
         | 
| 152 | 
            +
                      key: key,
         | 
| 153 | 
            +
                      content_type: content_type,
         | 
| 154 | 
            +
                      content_disposition: content_disposition,
         | 
| 155 | 
            +
                      part_size: part_size,
         | 
| 156 | 
            +
                      metadata: custom_metadata,
         | 
| 157 | 
            +
                      **upload_options
         | 
| 158 | 
            +
                    ) do |out|
         | 
| 143 159 | 
             
                      IO.copy_stream(io, out)
         | 
| 144 160 | 
             
                    end
         | 
| 145 161 | 
             
                  end
         | 
| 146 162 |  | 
| 147 | 
            -
             | 
| 148 163 | 
             
                  def object_for(key)
         | 
| 149 164 | 
             
                    bucket.object(key)
         | 
| 150 165 | 
             
                  end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: activestorage
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 7.2. | 
| 4 | 
            +
              version: 7.2.3
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - David Heinemeier Hansson
         | 
| @@ -15,56 +15,56 @@ dependencies: | |
| 15 15 | 
             
                requirements:
         | 
| 16 16 | 
             
                - - '='
         | 
| 17 17 | 
             
                  - !ruby/object:Gem::Version
         | 
| 18 | 
            -
                    version: 7.2. | 
| 18 | 
            +
                    version: 7.2.3
         | 
| 19 19 | 
             
              type: :runtime
         | 
| 20 20 | 
             
              prerelease: false
         | 
| 21 21 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 22 22 | 
             
                requirements:
         | 
| 23 23 | 
             
                - - '='
         | 
| 24 24 | 
             
                  - !ruby/object:Gem::Version
         | 
| 25 | 
            -
                    version: 7.2. | 
| 25 | 
            +
                    version: 7.2.3
         | 
| 26 26 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 27 27 | 
             
              name: actionpack
         | 
| 28 28 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 29 29 | 
             
                requirements:
         | 
| 30 30 | 
             
                - - '='
         | 
| 31 31 | 
             
                  - !ruby/object:Gem::Version
         | 
| 32 | 
            -
                    version: 7.2. | 
| 32 | 
            +
                    version: 7.2.3
         | 
| 33 33 | 
             
              type: :runtime
         | 
| 34 34 | 
             
              prerelease: false
         | 
| 35 35 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 36 36 | 
             
                requirements:
         | 
| 37 37 | 
             
                - - '='
         | 
| 38 38 | 
             
                  - !ruby/object:Gem::Version
         | 
| 39 | 
            -
                    version: 7.2. | 
| 39 | 
            +
                    version: 7.2.3
         | 
| 40 40 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 41 41 | 
             
              name: activejob
         | 
| 42 42 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 43 43 | 
             
                requirements:
         | 
| 44 44 | 
             
                - - '='
         | 
| 45 45 | 
             
                  - !ruby/object:Gem::Version
         | 
| 46 | 
            -
                    version: 7.2. | 
| 46 | 
            +
                    version: 7.2.3
         | 
| 47 47 | 
             
              type: :runtime
         | 
| 48 48 | 
             
              prerelease: false
         | 
| 49 49 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 50 50 | 
             
                requirements:
         | 
| 51 51 | 
             
                - - '='
         | 
| 52 52 | 
             
                  - !ruby/object:Gem::Version
         | 
| 53 | 
            -
                    version: 7.2. | 
| 53 | 
            +
                    version: 7.2.3
         | 
| 54 54 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 55 55 | 
             
              name: activerecord
         | 
| 56 56 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 57 57 | 
             
                requirements:
         | 
| 58 58 | 
             
                - - '='
         | 
| 59 59 | 
             
                  - !ruby/object:Gem::Version
         | 
| 60 | 
            -
                    version: 7.2. | 
| 60 | 
            +
                    version: 7.2.3
         | 
| 61 61 | 
             
              type: :runtime
         | 
| 62 62 | 
             
              prerelease: false
         | 
| 63 63 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 64 64 | 
             
                requirements:
         | 
| 65 65 | 
             
                - - '='
         | 
| 66 66 | 
             
                  - !ruby/object:Gem::Version
         | 
| 67 | 
            -
                    version: 7.2. | 
| 67 | 
            +
                    version: 7.2.3
         | 
| 68 68 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 69 69 | 
             
              name: marcel
         | 
| 70 70 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -189,10 +189,10 @@ licenses: | |
| 189 189 | 
             
            - MIT
         | 
| 190 190 | 
             
            metadata:
         | 
| 191 191 | 
             
              bug_tracker_uri: https://github.com/rails/rails/issues
         | 
| 192 | 
            -
              changelog_uri: https://github.com/rails/rails/blob/v7.2. | 
| 193 | 
            -
              documentation_uri: https://api.rubyonrails.org/v7.2. | 
| 192 | 
            +
              changelog_uri: https://github.com/rails/rails/blob/v7.2.3/activestorage/CHANGELOG.md
         | 
| 193 | 
            +
              documentation_uri: https://api.rubyonrails.org/v7.2.3/
         | 
| 194 194 | 
             
              mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
         | 
| 195 | 
            -
              source_code_uri: https://github.com/rails/rails/tree/v7.2. | 
| 195 | 
            +
              source_code_uri: https://github.com/rails/rails/tree/v7.2.3/activestorage
         | 
| 196 196 | 
             
              rubygems_mfa_required: 'true'
         | 
| 197 197 | 
             
            rdoc_options: []
         | 
| 198 198 | 
             
            require_paths:
         |