activestorage 8.1.3.1 → 8.1.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4b0ba7028cf3ec69f0c7e7658bf8b03993945ca49fce6c42a4b8f5c3cc4c4eb8
4
- data.tar.gz: 4524cbbb93d8e113d3af7bb065ed38d7f22b011def59f81f05e2e30862ea198d
3
+ metadata.gz: 363218fe84c4760d1243ee6f1325312eab52a4d1d7c33f512022e1a8ad4ed8a5
4
+ data.tar.gz: 603439dba3d29a9f57b433232954d85d9ec70905ab6114d10e370b2136283258
5
5
  SHA512:
6
- metadata.gz: b98acaa66a5bb64f6a0845ee8671085e0bef6b51599bb907cb75b02e67f4c088f53d97656448a8f351fb12447352020ffa3a7b7aca63677c90af42eab2de5b16
7
- data.tar.gz: d48b0a79c83c6bbf5b0eae9c3dd84f1c4c7dc762cc212c92d263a61275dfeabf7915eb4c0dfae46a68fa10b2a2fddc364e108a23b1073b3e6e11dbae19f263b6
6
+ metadata.gz: 5277345f853e82ae059c49bde6c2664f84516dfbd4da948e7a48b437da363682104b56fb895b75e7010f7201c5ced03106297c24bba67977a2567b045b2faa60
7
+ data.tar.gz: 27b8cbc33599414d28774b41d1d3891a1fb803e4316e217f24e47903f8a2d5e6f92fd7ffb2d50d9b02efddf26fa08ae6a199993dbbfc4cdad37aab813df1b906
data/CHANGELOG.md CHANGED
@@ -1,3 +1,69 @@
1
+ ## Rails 8.1.4 (September 24, 2026) ##
2
+
3
+ * Warn instead of aborting boot when `image_processing` 2.x is installed without `ruby-vips`
4
+ or `mini_magick`.
5
+
6
+ Both gems became soft dependencies in `image_processing` 2.0, and the `LoadError` raised for
7
+ a missing one names that gem instead of `image_processing`. Active Storage did not recognize
8
+ the message, so it re-raised rather than logging its usual warning.
9
+
10
+ Fixes #58413.
11
+
12
+ *Janko Marohnić*
13
+
14
+ * Fix `MirrorService#mirror` losing blob metadata when copying to mirrors.
15
+
16
+ Mirrored copies on S3, Azure, and GCS were served as `application/octet-stream`
17
+ because `content_type`, `filename`, `disposition`, and `custom_metadata` were
18
+ dropped. Forward the blob's `service_metadata` to each mirror's upload.
19
+
20
+ Fixes #57270.
21
+
22
+ *Maksim Romanov* + *Andrii Furmanets*
23
+
24
+ * Prevent `ActiveStorage.touch_attachment_records = false` from crashing the attachment of a Blob.
25
+
26
+ When `ActiveStorage.touch_attachment_records` was set to `false`, attaching a existing Blob to a Record
27
+ would raise an error. This is now fixed.
28
+
29
+ *Edouard Chin*
30
+
31
+ * Fix `MirrorService#mirror` raising `ActiveStorage::IntegrityError` when
32
+ mirroring without a checksum (e.g., `track_variants: false`).
33
+
34
+ *Denis Savchuk*
35
+
36
+ * Preserve attachment changes when converting record to another class using STI.
37
+
38
+ *fatkodima*
39
+
40
+ * Correct unexpected behavior resulting from dependent: :purge when using
41
+ has_one_attached or has_many_attached. Fixes #36423.
42
+
43
+ *Mark Oveson*
44
+
45
+ * Define `as_json` on `ActiveStorage::Attached::One` and `ActiveStorage::Attached::Many`.
46
+
47
+ The proxies hold a back-reference to the owning record in `@record`. Without an explicit
48
+ `as_json`, the default `Object#as_json` fall back serialized `instance_values`, which made
49
+ `record.to_json` recurse infinitely whenever the attached name collided with a model
50
+ attribute (e.g. an `ignored_columns` column brought back by `select('*')`).
51
+
52
+ `Attached::One#as_json` now returns the attachment record's JSON when attached and `nil`
53
+ otherwise. `Attached::Many#as_json` returns the attachment records' JSON as an array.
54
+
55
+ *Renxiang Cai*
56
+
57
+ * Fix Rails hanging when generating video previews
58
+
59
+ When Rails runs in a background process group, ffmpeg's attempt to configure the terminal for
60
+ interactive input would send SIGTTOU to the Rails process, suspending it indefinitely.
61
+
62
+ Fixed by explicitly passing /dev/null to ffmpeg's stdin.
63
+
64
+ *Jonathan del Strother*
65
+
66
+
1
67
  ## Rails 8.1.3.1 (July 29, 2026) ##
2
68
 
3
69
  * Disable libvips's unfuzzed image loaders and savers.
@@ -1,10 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Proxy files through application. This avoids having a redirect and makes files easier to cache.
3
+ # Finds a blob by a +signed_id+ and proxies the file through the application.
4
+ # The blob is streamed from storage directly to the response. This avoids having
5
+ # a redirect and makes files easier to cache.
4
6
  #
5
- # WARNING: All Active Storage controllers are publicly accessible by default. The
6
- # generated URLs are hard to guess, but permanent by design. If your files
7
- # require a higher level of protection consider implementing
7
+ # The +signed_id+s make URLs hard to guess but permanent by design, allowing the URLs to be cached.
8
+ # The response sets the HTTP cache to public and allows browsers and proxies to cache it indefinitely.
9
+ #
10
+ # The URLs created for this controller are set to never expire by default.
11
+ # To make URLs expire, pass the +expires_in+ option when generating the URL:
12
+ #
13
+ # rails_storage_proxy_url(blob, expires_in: 1.minute)
14
+ #
15
+ # Or set the default for all Active Storage URLs:
16
+ #
17
+ # config.active_storage.urls_expire_in = 1.day
18
+ #
19
+ # WARNING: All Active Storage controllers are publicly accessible by default.
20
+ # Anyone who knows the URL can access the file, even if the rest of your application requires
21
+ # authentication. If your files require access control consider implementing
8
22
  # {Authenticated Controllers}[https://guides.rubyonrails.org/active_storage_overview.html#authenticated-controllers].
9
23
  class ActiveStorage::Blobs::ProxyController < ActiveStorage::BaseController
10
24
  include ActiveStorage::SetBlob
@@ -1,10 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Take a signed permanent reference for a blob and turn it into an expiring service URL for download.
3
+ # Finds a blob by a +signed_id+ and redirects to a blob's expiring service URL.
4
4
  #
5
- # WARNING: All Active Storage controllers are publicly accessible by default. The
6
- # generated URLs are hard to guess, but permanent by design. If your files
7
- # require a higher level of protection consider implementing
5
+ # The +signed_id+s make URLs hard to guess but permanent by design, allowing the URLs to be cached.
6
+ #
7
+ # The URLs created for this controller are set to never expire by default.
8
+ # To make URLs expire, pass the +expires_in+ option when generating the URL:
9
+ #
10
+ # rails_storage_redirect_url(blob, expires_in: 1.minute)
11
+ #
12
+ # Or set the default for all Active Storage URLs:
13
+ #
14
+ # config.active_storage.urls_expire_in = 1.day
15
+ #
16
+ # The service URLs are set to expire in 5 minutes by default.
17
+ # The default can be changed for all service URLs:
18
+ #
19
+ # config.active_storage.service_urls_expire_in = 1.hour
20
+ #
21
+ # WARNING: All Active Storage controllers are publicly accessible by default.
22
+ # Anyone who knows the URL can access the file, even if the rest of your application requires
23
+ # authentication. If your files require access control consider implementing
8
24
  # {Authenticated Controllers}[https://guides.rubyonrails.org/active_storage_overview.html#authenticated-controllers].
9
25
  class ActiveStorage::Blobs::RedirectController < ActiveStorage::BaseController
10
26
  include ActiveStorage::SetBlob
@@ -1,10 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Proxy files through application. This avoids having a redirect and makes files easier to cache.
3
+ # Finds a representation by a +signed_id+ and a +variation_key+, and proxies the file through the application.
4
+ # The representation is streamed from storage directly to the response. This avoids having
5
+ # a redirect and makes files easier to cache.
4
6
  #
5
- # WARNING: All Active Storage controllers are publicly accessible by default. The
6
- # generated URLs are hard to guess, but permanent by design. If your files
7
- # require a higher level of protection consider implementing
7
+ # The +signed_id+s make URLs hard to guess but permanent by design, allowing the URLs to be cached.
8
+ # The response sets the HTTP cache to public and allows browsers and proxies to cache it indefinitely.
9
+ #
10
+ # The URLs created for this controller are set to never expire by default.
11
+ # To make URLs expire, pass the +expires_in+ option when generating the URL:
12
+ #
13
+ # rails_storage_proxy_url(representation, expires_in: 1.minute)
14
+ #
15
+ # Or set the default for all Active Storage URLs:
16
+ #
17
+ # config.active_storage.urls_expire_in = 1.day
18
+ #
19
+ # WARNING: All Active Storage controllers are publicly accessible by default.
20
+ # Anyone who knows the URL can access the file, even if the rest of your application requires
21
+ # authentication. If your files require access control consider implementing
8
22
  # {Authenticated Controllers}[https://guides.rubyonrails.org/active_storage_overview.html#authenticated-controllers].
9
23
  class ActiveStorage::Representations::ProxyController < ActiveStorage::Representations::BaseController
10
24
  include ActiveStorage::Streaming
@@ -1,10 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Take a signed permanent reference for a blob representation and turn it into an expiring service URL for download.
3
+ # Finds a representation by a +signed_id+ and a +variation_key+, and redirects to a representation's expiring
4
+ # service URL.
4
5
  #
5
- # WARNING: All Active Storage controllers are publicly accessible by default. The
6
- # generated URLs are hard to guess, but permanent by design. If your files
7
- # require a higher level of protection consider implementing
6
+ # The +signed_id+s make URLs hard to guess but permanent by design, allowing the URLs to be cached.
7
+ #
8
+ # The URLs created for this controller are set to never expire by default.
9
+ # To make URLs expire, pass the +expires_in+ option when generating the URL:
10
+ #
11
+ # rails_storage_redirect_url(representation, expires_in: 1.minute)
12
+ #
13
+ # Or set the default for all Active Storage URLs:
14
+ #
15
+ # config.active_storage.urls_expire_in = 1.day
16
+ #
17
+ # The service URLs are set to expire in 5 minutes by default.
18
+ # The default can be changed for all service URLs:
19
+ #
20
+ # config.active_storage.service_urls_expire_in = 1.hour
21
+ #
22
+ # WARNING: All Active Storage controllers are publicly accessible by default.
23
+ # Anyone who knows the URL can access the file, even if the rest of your application requires
24
+ # authentication. If your files require access control consider implementing
8
25
  # {Authenticated Controllers}[https://guides.rubyonrails.org/active_storage_overview.html#authenticated-controllers].
9
26
  class ActiveStorage::Representations::RedirectController < ActiveStorage::Representations::BaseController
10
27
  def show
@@ -34,7 +34,7 @@ class ActiveStorage::Attachment < ActiveStorage::Record
34
34
  delegate :signed_id, to: :blob
35
35
 
36
36
  after_create_commit :mirror_blob_later, :analyze_blob_later, :transform_variants_later
37
- after_destroy_commit :purge_dependent_blob_later
37
+ after_destroy_commit :purge_dependent_blob
38
38
 
39
39
  ##
40
40
  # :singleton-method:
@@ -147,8 +147,12 @@ class ActiveStorage::Attachment < ActiveStorage::Record
147
147
  end
148
148
  end
149
149
 
150
- def purge_dependent_blob_later
151
- blob&.purge_later if dependent == :purge_later
150
+ def purge_dependent_blob
151
+ if dependent == :purge_later
152
+ blob&.purge_later
153
+ elsif dependent == :purge
154
+ blob&.purge
155
+ end
152
156
  end
153
157
 
154
158
  def dependent
@@ -282,6 +282,16 @@ class ActiveStorage::Blob < ActiveStorage::Record
282
282
  service.compose(keys, key, **service_metadata)
283
283
  end
284
284
 
285
+ def service_metadata # :nodoc:
286
+ if forcibly_serve_as_binary?
287
+ { content_type: ActiveStorage.binary_content_type, disposition: :attachment, filename: filename, custom_metadata: custom_metadata }
288
+ elsif !allowed_inline?
289
+ { content_type: content_type, disposition: :attachment, filename: filename, custom_metadata: custom_metadata }
290
+ else
291
+ { content_type: content_type, custom_metadata: custom_metadata }
292
+ end
293
+ end
294
+
285
295
  # Downloads the file associated with this blob. If no block is given, the entire file is read into memory and returned.
286
296
  # That'll use a lot of RAM for very large files. If a block is given, then the download is streamed and yielded in chunks.
287
297
  def download(&block)
@@ -371,16 +381,6 @@ class ActiveStorage::Blob < ActiveStorage::Record
371
381
  ActiveStorage.web_image_content_types.include?(content_type)
372
382
  end
373
383
 
374
- def service_metadata
375
- if forcibly_serve_as_binary?
376
- { content_type: ActiveStorage.binary_content_type, disposition: :attachment, filename: filename, custom_metadata: custom_metadata }
377
- elsif !allowed_inline?
378
- { content_type: content_type, disposition: :attachment, filename: filename, custom_metadata: custom_metadata }
379
- else
380
- { content_type: content_type, custom_metadata: custom_metadata }
381
- end
382
- end
383
-
384
384
  def touch_attachments
385
385
  attachments.then do |relation|
386
386
  if ActiveStorage.touch_attachment_records
@@ -389,7 +389,7 @@ class ActiveStorage::Blob < ActiveStorage::Record
389
389
  relation
390
390
  end
391
391
  end.each do |attachment|
392
- attachment.touch
392
+ attachment.touch unless attachment.new_record?
393
393
  end
394
394
  end
395
395
 
@@ -78,7 +78,7 @@ class ActiveStorage::Variant
78
78
  #
79
79
  # Use <tt>url_for(variant)</tt> (or the implied form, like <tt>link_to variant</tt> or <tt>redirect_to variant</tt>) to get the stable URL
80
80
  # for a variant that points to the ActiveStorage::Representations::ProxyController or ActiveStorage::Representations::RedirectController,
81
- # which in turn will use this +service_call+ method for its redirection.
81
+ # which in turn will use this +url+ method for its redirection.
82
82
  def url(expires_in: ActiveStorage.service_urls_expire_in, disposition: :inline)
83
83
  service.url key, expires_in: expires_in, disposition: disposition, filename: filename, content_type: content_type
84
84
  end
@@ -2,7 +2,8 @@
2
2
 
3
3
  module ActiveStorage
4
4
  class Attached::Changes::CreateMany # :nodoc:
5
- attr_reader :name, :record, :attachables, :pending_uploads
5
+ attr_reader :name, :attachables, :pending_uploads
6
+ attr_accessor :record
6
7
 
7
8
  def initialize(name, record, attachables, pending_uploads: [])
8
9
  @name, @record, @attachables = name, record, Array(attachables)
@@ -5,7 +5,8 @@ require "action_dispatch/http/upload"
5
5
 
6
6
  module ActiveStorage
7
7
  class Attached::Changes::CreateOne # :nodoc:
8
- attr_reader :name, :record, :attachable
8
+ attr_reader :name, :attachable
9
+ attr_accessor :record
9
10
 
10
11
  def initialize(name, record, attachable)
11
12
  @name, @record, @attachable = name, record, attachable
@@ -2,7 +2,8 @@
2
2
 
3
3
  module ActiveStorage
4
4
  class Attached::Changes::DeleteMany # :nodoc:
5
- attr_reader :name, :record
5
+ attr_reader :name
6
+ attr_accessor :record
6
7
 
7
8
  def initialize(name, record)
8
9
  @name, @record = name, record
@@ -2,7 +2,8 @@
2
2
 
3
3
  module ActiveStorage
4
4
  class Attached::Changes::DeleteOne # :nodoc:
5
- attr_reader :name, :record
5
+ attr_reader :name
6
+ attr_accessor :record
6
7
 
7
8
  def initialize(name, record)
8
9
  @name, @record = name, record
@@ -67,6 +67,10 @@ module ActiveStorage
67
67
  attachments.any?
68
68
  end
69
69
 
70
+ def as_json(options = nil)
71
+ attachments.as_json(options)
72
+ end
73
+
70
74
  private
71
75
  def purge_many
72
76
  Attached::Changes::PurgeMany.new(name, record, attachments)
@@ -75,7 +75,7 @@ module ActiveStorage
75
75
  # The +:dependent+ option defaults to +:purge_later+. This means the attachment will be
76
76
  # purged (i.e. destroyed) in the background whenever the record is destroyed.
77
77
  # If an ActiveJob::Backend queue adapter is not set in the application set it to
78
- # +purge+ instead.
78
+ # +:purge+ instead.
79
79
  #
80
80
  # If you need the attachment to use a service which differs from the globally configured one,
81
81
  # pass the +:service+ option. For example:
@@ -177,7 +177,7 @@ module ActiveStorage
177
177
  # The +:dependent+ option defaults to +:purge_later+. This means the attachments will be
178
178
  # purged (i.e. destroyed) in the background whenever the record is destroyed.
179
179
  # If an ActiveJob::Backend queue adapter is not set in the application set it to
180
- # +purge+ instead.
180
+ # +:purge+ instead.
181
181
  #
182
182
  # If you need the attachment to use a service which differs from the globally configured one,
183
183
  # pass the +:service+ option. For example:
@@ -278,6 +278,8 @@ module ActiveStorage
278
278
  end
279
279
  end
280
280
 
281
+ attr_writer :attachment_changes # :nodoc:
282
+
281
283
  def attachment_changes # :nodoc:
282
284
  @attachment_changes ||= {}
283
285
  end
@@ -295,5 +297,14 @@ module ActiveStorage
295
297
  def reload(*) # :nodoc:
296
298
  super.tap { @attachment_changes = nil }
297
299
  end
300
+
301
+ def becomes(klass) # :nodoc:
302
+ super.tap do |became|
303
+ attachment_changes = @attachment_changes&.each_value do |change|
304
+ change.record = became
305
+ end
306
+ became.attachment_changes = attachment_changes
307
+ end
308
+ end
298
309
  end
299
310
  end
@@ -45,6 +45,12 @@ module ActiveStorage
45
45
  !attached?
46
46
  end
47
47
 
48
+ # Returns the attachment record's JSON representation, or +nil+ when no
49
+ # attachment is present.
50
+ def as_json(options = nil)
51
+ attached? ? attachment.as_json(options) : nil
52
+ end
53
+
48
54
  # Attaches an +attachable+ to the record.
49
55
  #
50
56
  # If the record is persisted and unchanged, the attachment is saved to
@@ -115,6 +115,16 @@ module ActiveStorage
115
115
  Please add `gem "image_processing", "~> 1.2"` to your Gemfile
116
116
  or set `config.active_storage.variant_processor = :disabled`.
117
117
  WARNING
118
+ when /ruby-vips/
119
+ ActiveStorage.logger.warn <<~WARNING.squish
120
+ Generating image variants with libvips requires the ruby-vips gem.
121
+ Please add `gem "ruby-vips", "~> 2.3"` to your Gemfile.
122
+ WARNING
123
+ when /mini_magick/
124
+ ActiveStorage.logger.warn <<~WARNING.squish
125
+ Generating image variants with ImageMagick requires the mini_magick gem.
126
+ Please add `gem "mini_magick", "~> 5.0"` to your Gemfile.
127
+ WARNING
118
128
  else
119
129
  raise
120
130
  end
@@ -9,8 +9,8 @@ module ActiveStorage
9
9
  module VERSION
10
10
  MAJOR = 8
11
11
  MINOR = 1
12
- TINY = 3
13
- PRE = "1"
12
+ TINY = 4
13
+ PRE = nil
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -79,7 +79,7 @@ module ActiveStorage
79
79
  to.binmode
80
80
 
81
81
  open_tempfile do |err|
82
- IO.popen(argv, err: err) { |out| IO.copy_stream(out, to) }
82
+ IO.popen(argv, in: IO::NULL, err: err) { |out| IO.copy_stream(out, to) }
83
83
  err.rewind
84
84
 
85
85
  unless $?.success?
@@ -7,7 +7,7 @@ module ActiveStorage
7
7
  # Wraps a set of mirror services and provides a single ActiveStorage::Service object that will all
8
8
  # have the files uploaded to them. A +primary+ service is designated to answer calls to:
9
9
  # * +download+
10
- # * +exists?+
10
+ # * +exist?+
11
11
  # * +url+
12
12
  # * +url_for_direct_upload+
13
13
  # * +headers_for_direct_upload+
@@ -66,10 +66,12 @@ module ActiveStorage
66
66
  def mirror(key, checksum:)
67
67
  instrument :mirror, key: key, checksum: checksum do
68
68
  if (mirrors_in_need_of_mirroring = mirrors.select { |service| !service.exist?(key) }).any?
69
- primary.open(key, checksum: checksum) do |io|
69
+ metadata = ActiveStorage::Blob.find_by(key: key)&.service_metadata || {}
70
+
71
+ primary.open(key, checksum: checksum, verify: checksum.present?) do |io|
70
72
  mirrors_in_need_of_mirroring.each do |service|
71
73
  io.rewind
72
- service.upload key, io, checksum: checksum
74
+ service.upload key, io, checksum: checksum, **metadata
73
75
  end
74
76
  end
75
77
  end
@@ -34,6 +34,7 @@ require "active_storage/deprecator"
34
34
  require "active_storage/errors"
35
35
 
36
36
  require "marcel"
37
+ require "openssl"
37
38
 
38
39
  # :markup: markdown
39
40
  # :include: ../README.md
@@ -358,6 +359,9 @@ module ActiveStorage
358
359
  mattr_accessor :touch_attachment_records, default: true
359
360
  mattr_accessor :urls_expire_in
360
361
 
362
+ # Configures the mount point for the default Active Storage routes. Accepts any
363
+ # value supported by `scope`, such as a string path prefix or a hash of routing
364
+ # options.
361
365
  mattr_accessor :routes_prefix, default: "/rails/active_storage"
362
366
  mattr_accessor :draw_routes, default: true
363
367
  mattr_accessor :resolve_model_to_route, default: :rails_storage_redirect
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: 8.1.3.1
4
+ version: 8.1.4
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: 8.1.3.1
18
+ version: 8.1.4
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: 8.1.3.1
25
+ version: 8.1.4
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: 8.1.3.1
32
+ version: 8.1.4
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: 8.1.3.1
39
+ version: 8.1.4
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: 8.1.3.1
46
+ version: 8.1.4
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: 8.1.3.1
53
+ version: 8.1.4
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: 8.1.3.1
60
+ version: 8.1.4
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: 8.1.3.1
67
+ version: 8.1.4
68
68
  - !ruby/object:Gem::Dependency
69
69
  name: marcel
70
70
  requirement: !ruby/object:Gem::Requirement
@@ -193,10 +193,10 @@ licenses:
193
193
  - MIT
194
194
  metadata:
195
195
  bug_tracker_uri: https://github.com/rails/rails/issues
196
- changelog_uri: https://github.com/rails/rails/blob/v8.1.3.1/activestorage/CHANGELOG.md
197
- documentation_uri: https://api.rubyonrails.org/v8.1.3.1/
196
+ changelog_uri: https://github.com/rails/rails/blob/v8.1.4/activestorage/CHANGELOG.md
197
+ documentation_uri: https://api.rubyonrails.org/v8.1.4/
198
198
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
199
- source_code_uri: https://github.com/rails/rails/tree/v8.1.3.1/activestorage
199
+ source_code_uri: https://github.com/rails/rails/tree/v8.1.4/activestorage
200
200
  rubygems_mfa_required: 'true'
201
201
  rdoc_options: []
202
202
  require_paths:
@@ -212,7 +212,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
212
212
  - !ruby/object:Gem::Version
213
213
  version: '0'
214
214
  requirements: []
215
- rubygems_version: 4.0.16
215
+ rubygems_version: 4.0.20
216
216
  specification_version: 4
217
217
  summary: Local and cloud file storage framework.
218
218
  test_files: []