activestorage 7.2.2 → 8.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -87
- data/README.md +2 -2
- data/app/assets/javascripts/activestorage.esm.js +1 -1
- data/app/assets/javascripts/activestorage.js +1 -0
- data/app/controllers/active_storage/direct_uploads_controller.rb +1 -1
- data/app/controllers/concerns/active_storage/streaming.rb +9 -0
- data/app/javascript/activestorage/index.js +2 -1
- data/app/models/active_storage/blob/representable.rb +3 -3
- data/app/models/active_storage/blob.rb +2 -3
- data/app/models/active_storage/filename.rb +1 -1
- data/lib/active_storage/attached/model.rb +16 -12
- data/lib/active_storage/gem_version.rb +4 -4
- data/lib/active_storage/service/azure_storage_service.rb +7 -0
- data/lib/active_storage/service/mirror_service.rb +12 -3
- metadata +14 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 90eb90580cb0faea4b29eef5ddf0dbc99dd1087158980f968561fe45c2dcb4d4
|
4
|
+
data.tar.gz: bdd0ced8684956539dee4f32ea7eacd16744c72e318aebc0bd815adfa72ffe73
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 46465038ab95d65913a9f359af9b21fcb5b3ee9a37877b32eeabd7943de6373625d7ae51a9383099a89bd7d949ee6b5db37c5518656313121d8991b4e52e7667
|
7
|
+
data.tar.gz: 4f7590242bb707d2ed0c9b22871f2e00d28f683224341387c739b9771a85ab18e8655e1a913b2bdabb724bb694cb6b997f4b1c2771fa52a2b96ac1882593471a
|
data/CHANGELOG.md
CHANGED
@@ -1,98 +1,23 @@
|
|
1
|
-
## Rails
|
1
|
+
## Rails 8.0.0.beta1 (September 26, 2024) ##
|
2
2
|
|
3
|
-
*
|
3
|
+
* Deprecate `ActiveStorage::Service::AzureStorageService`.
|
4
4
|
|
5
|
+
*zzak*
|
5
6
|
|
6
|
-
|
7
|
+
* Improve `ActiveStorage::Filename#sanitized` method to handle special characters more effectively.
|
8
|
+
Replace the characters `"*?<>` with `-` if they exist in the Filename to match the Filename convention of Win OS.
|
7
9
|
|
8
|
-
*
|
10
|
+
*Luong Viet Dung(Martin)*
|
9
11
|
|
12
|
+
* Improve InvariableError, UnpreviewableError and UnrepresentableError message.
|
10
13
|
|
11
|
-
|
14
|
+
Include Blob ID and content_type in the messages.
|
12
15
|
|
13
|
-
*
|
16
|
+
*Petrik de Heus*
|
14
17
|
|
18
|
+
* Mark proxied files as `immutable` in their Cache-Control header
|
15
19
|
|
16
|
-
|
20
|
+
*Nate Matykiewicz*
|
17
21
|
|
18
|
-
* No changes.
|
19
22
|
|
20
|
-
|
21
|
-
## Rails 7.2.0 (August 09, 2024) ##
|
22
|
-
|
23
|
-
* Remove deprecated `config.active_storage.silence_invalid_content_types_warning`.
|
24
|
-
|
25
|
-
*Rafael Mendonça França*
|
26
|
-
|
27
|
-
* Remove deprecated `config.active_storage.replace_on_assign_to_many`.
|
28
|
-
|
29
|
-
*Rafael Mendonça França*
|
30
|
-
|
31
|
-
* Add support for custom `key` in `ActiveStorage::Blob#compose`.
|
32
|
-
|
33
|
-
*Elvin Efendiev*
|
34
|
-
|
35
|
-
* Add `image/webp` to `config.active_storage.web_image_content_types` when `load_defaults "7.2"`
|
36
|
-
is set.
|
37
|
-
|
38
|
-
*Lewis Buckley*
|
39
|
-
|
40
|
-
* Fix JSON-encoding of `ActiveStorage::Filename` instances.
|
41
|
-
|
42
|
-
*Jonathan del Strother*
|
43
|
-
|
44
|
-
* Fix N+1 query when fetching preview images for non-image assets.
|
45
|
-
|
46
|
-
*Aaron Patterson & Justin Searls*
|
47
|
-
|
48
|
-
* Fix all Active Storage database related models to respect
|
49
|
-
`ActiveRecord::Base.table_name_prefix` configuration.
|
50
|
-
|
51
|
-
*Chedli Bourguiba*
|
52
|
-
|
53
|
-
* Fix `ActiveStorage::Representations::ProxyController` not returning the proper
|
54
|
-
preview image variant for previewable files.
|
55
|
-
|
56
|
-
*Chedli Bourguiba*
|
57
|
-
|
58
|
-
* Fix `ActiveStorage::Representations::ProxyController` to proxy untracked
|
59
|
-
variants.
|
60
|
-
|
61
|
-
*Chedli Bourguiba*
|
62
|
-
|
63
|
-
* When using the `preprocessed: true` option, avoid enqueuing transform jobs
|
64
|
-
for blobs that are not representable.
|
65
|
-
|
66
|
-
*Chedli Bourguiba*
|
67
|
-
|
68
|
-
* Prevent `ActiveStorage::Blob#preview` to generate a variant if an empty variation is passed.
|
69
|
-
|
70
|
-
Calls to `#url`, `#key` or `#download` will now use the original preview
|
71
|
-
image instead of generating a variant with the exact same dimensions.
|
72
|
-
|
73
|
-
*Chedli Bourguiba*
|
74
|
-
|
75
|
-
* Process preview image variant when calling `ActiveStorage::Preview#processed`.
|
76
|
-
|
77
|
-
For example, `attached_pdf.preview(:thumb).processed` will now immediately
|
78
|
-
generate the full-sized preview image and the `:thumb` variant of it.
|
79
|
-
Previously, the `:thumb` variant would not be generated until a further call
|
80
|
-
to e.g. `processed.url`.
|
81
|
-
|
82
|
-
*Chedli Bourguiba* and *Jonathan Hefner*
|
83
|
-
|
84
|
-
* Prevent `ActiveRecord::StrictLoadingViolationError` when strict loading is
|
85
|
-
enabled and the variant of an Active Storage preview has already been
|
86
|
-
processed (for example, by calling `ActiveStorage::Preview#url`).
|
87
|
-
|
88
|
-
*Jonathan Hefner*
|
89
|
-
|
90
|
-
* Fix `preprocessed: true` option for named variants of previewable files.
|
91
|
-
|
92
|
-
*Nico Wenterodt*
|
93
|
-
|
94
|
-
* Allow accepting `service` as a proc as well in `has_one_attached` and `has_many_attached`.
|
95
|
-
|
96
|
-
*Yogesh Khater*
|
97
|
-
|
98
|
-
Please check [7-1-stable](https://github.com/rails/rails/blob/7-1-stable/activestorage/CHANGELOG.md) for previous changes.
|
23
|
+
Please check [7-2-stable](https://github.com/rails/rails/blob/7-2-stable/activestorage/CHANGELOG.md) for previous changes.
|
data/README.md
CHANGED
@@ -73,7 +73,7 @@ end
|
|
73
73
|
```erb
|
74
74
|
<%= form_with model: @message, local: true do |form| %>
|
75
75
|
<%= form.text_field :title, placeholder: "Title" %><br>
|
76
|
-
<%= form.
|
76
|
+
<%= form.textarea :content %><br><br>
|
77
77
|
|
78
78
|
<%= form.file_field :images, multiple: true %><br>
|
79
79
|
<%= form.submit %>
|
@@ -88,7 +88,7 @@ class MessagesController < ApplicationController
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def create
|
91
|
-
message = Message.create! params.
|
91
|
+
message = Message.create! params.expect(message: [ :title, :content, images: [] ])
|
92
92
|
redirect_to message
|
93
93
|
end
|
94
94
|
|
@@ -822,6 +822,7 @@
|
|
822
822
|
exports.DirectUpload = DirectUpload;
|
823
823
|
exports.DirectUploadController = DirectUploadController;
|
824
824
|
exports.DirectUploadsController = DirectUploadsController;
|
825
|
+
exports.dispatchEvent = dispatchEvent;
|
825
826
|
exports.start = start;
|
826
827
|
Object.defineProperty(exports, "__esModule", {
|
827
828
|
value: true
|
@@ -11,7 +11,7 @@ class ActiveStorage::DirectUploadsController < ActiveStorage::BaseController
|
|
11
11
|
|
12
12
|
private
|
13
13
|
def blob_args
|
14
|
-
params.
|
14
|
+
params.expect(blob: [:filename, :byte_size, :checksum, :content_type, metadata: {}]).to_h.symbolize_keys
|
15
15
|
end
|
16
16
|
|
17
17
|
def direct_upload_json(blob)
|
@@ -61,6 +61,15 @@ module ActiveStorage::Streaming
|
|
61
61
|
blob.download do |chunk|
|
62
62
|
stream.write chunk
|
63
63
|
end
|
64
|
+
rescue ActiveStorage::FileNotFoundError
|
65
|
+
expires_now
|
66
|
+
head :not_found
|
67
|
+
rescue
|
68
|
+
# Status and caching headers are already set, but not commited.
|
69
|
+
# Change the status to 500 manually.
|
70
|
+
expires_now
|
71
|
+
head :internal_server_error
|
72
|
+
raise
|
64
73
|
end
|
65
74
|
end
|
66
75
|
end
|
@@ -2,7 +2,8 @@ import { start } from "./ujs"
|
|
2
2
|
import { DirectUpload } from "./direct_upload"
|
3
3
|
import { DirectUploadController } from "./direct_upload_controller"
|
4
4
|
import { DirectUploadsController } from "./direct_uploads_controller"
|
5
|
-
|
5
|
+
import { dispatchEvent } from "./helpers"
|
6
|
+
export { start, DirectUpload, DirectUploadController, DirectUploadsController, dispatchEvent }
|
6
7
|
|
7
8
|
function autostart() {
|
8
9
|
if (window.ActiveStorage) {
|
@@ -35,7 +35,7 @@ module ActiveStorage::Blob::Representable
|
|
35
35
|
if variable?
|
36
36
|
variant_class.new(self, ActiveStorage::Variation.wrap(transformations).default_to(default_variant_transformations))
|
37
37
|
else
|
38
|
-
raise ActiveStorage::InvariableError
|
38
|
+
raise ActiveStorage::InvariableError, "Can't transform blob with ID=#{id} and content_type=#{content_type}"
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -64,7 +64,7 @@ module ActiveStorage::Blob::Representable
|
|
64
64
|
if previewable?
|
65
65
|
ActiveStorage::Preview.new(self, transformations)
|
66
66
|
else
|
67
|
-
raise ActiveStorage::UnpreviewableError
|
67
|
+
raise ActiveStorage::UnpreviewableError, "No previewer found for blob with ID=#{id} and content_type=#{content_type}"
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
@@ -89,7 +89,7 @@ module ActiveStorage::Blob::Representable
|
|
89
89
|
when variable?
|
90
90
|
variant transformations
|
91
91
|
else
|
92
|
-
raise ActiveStorage::UnrepresentableError
|
92
|
+
raise ActiveStorage::UnrepresentableError, "No previewer found and can't transform blob with ID=#{id} and content_type=#{content_type}"
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
@@ -71,9 +71,8 @@ class ActiveStorage::Blob < ActiveStorage::Record
|
|
71
71
|
end
|
72
72
|
|
73
73
|
# Works like +find_signed+, but will raise an +ActiveSupport::MessageVerifier::InvalidSignature+
|
74
|
-
# exception if the +signed_id+ has either expired, has a purpose mismatch,
|
75
|
-
#
|
76
|
-
# the valid signed id can't find a record.
|
74
|
+
# exception if the +signed_id+ has either expired, has a purpose mismatch, or has been tampered with.
|
75
|
+
# It will also raise an +ActiveRecord::RecordNotFound+ exception if the valid signed id can't find a record.
|
77
76
|
def find_signed!(id, record: nil, purpose: :blob_id)
|
78
77
|
super(id, purpose: purpose)
|
79
78
|
end
|
@@ -57,7 +57,7 @@ class ActiveStorage::Filename
|
|
57
57
|
#
|
58
58
|
# Characters considered unsafe for storage (e.g. \, $, and the RTL override character) are replaced with a dash.
|
59
59
|
def sanitized
|
60
|
-
@filename.encode(Encoding::UTF_8, invalid: :replace, undef: :replace, replace: "�").strip.tr("\u{202E}
|
60
|
+
@filename.encode(Encoding::UTF_8, invalid: :replace, undef: :replace, replace: "�").strip.tr("\u{202E}%$|:;/<>?*\"\t\r\n\\", "-")
|
61
61
|
end
|
62
62
|
|
63
63
|
# Returns the sanitized version of the filename.
|
@@ -61,18 +61,16 @@ module ActiveStorage
|
|
61
61
|
# There is no column defined on the model side, Active Storage takes
|
62
62
|
# care of the mapping between your records and the attachment.
|
63
63
|
#
|
64
|
-
# To avoid N+1 queries, you can include the attached blobs in your query like so:
|
65
|
-
#
|
66
|
-
# User.with_attached_avatar
|
67
|
-
#
|
68
64
|
# Under the covers, this relationship is implemented as a +has_one+ association to a
|
69
65
|
# ActiveStorage::Attachment record and a +has_one-through+ association to a
|
70
66
|
# ActiveStorage::Blob record. These associations are available as +avatar_attachment+
|
71
67
|
# and +avatar_blob+. But you shouldn't need to work with these associations directly in
|
72
68
|
# most circumstances.
|
73
69
|
#
|
74
|
-
#
|
75
|
-
#
|
70
|
+
# Instead, +has_one_attached+ generates an ActiveStorage::Attached::One proxy to
|
71
|
+
# provide access to the associations and factory methods, like +attach+:
|
72
|
+
#
|
73
|
+
# user.avatar.attach(uploaded_file)
|
76
74
|
#
|
77
75
|
# The +:dependent+ option defaults to +:purge_later+. This means the attachment will be
|
78
76
|
# purged (i.e. destroyed) in the background whenever the record is destroyed.
|
@@ -92,6 +90,10 @@ module ActiveStorage
|
|
92
90
|
# has_one_attached :avatar, service: ->(user) { user.in_europe_region? ? :s3_europe : :s3_usa }
|
93
91
|
# end
|
94
92
|
#
|
93
|
+
# To avoid N+1 queries, you can include the attached blobs in your query like so:
|
94
|
+
#
|
95
|
+
# User.with_attached_avatar
|
96
|
+
#
|
95
97
|
# If you need to enable +strict_loading+ to prevent lazy loading of attachment,
|
96
98
|
# pass the +:strict_loading+ option. You can do:
|
97
99
|
#
|
@@ -161,18 +163,16 @@ module ActiveStorage
|
|
161
163
|
# There are no columns defined on the model side, Active Storage takes
|
162
164
|
# care of the mapping between your records and the attachments.
|
163
165
|
#
|
164
|
-
# To avoid N+1 queries, you can include the attached blobs in your query like so:
|
165
|
-
#
|
166
|
-
# Gallery.where(user: Current.user).with_attached_photos
|
167
|
-
#
|
168
166
|
# Under the covers, this relationship is implemented as a +has_many+ association to a
|
169
167
|
# ActiveStorage::Attachment record and a +has_many-through+ association to a
|
170
168
|
# ActiveStorage::Blob record. These associations are available as +photos_attachments+
|
171
169
|
# and +photos_blobs+. But you shouldn't need to work with these associations directly in
|
172
170
|
# most circumstances.
|
173
171
|
#
|
174
|
-
#
|
175
|
-
#
|
172
|
+
# Instead, +has_many_attached+ generates an ActiveStorage::Attached::Many proxy to
|
173
|
+
# provide access to the associations and factory methods, like +attach+:
|
174
|
+
#
|
175
|
+
# user.photos.attach(uploaded_file)
|
176
176
|
#
|
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.
|
@@ -192,6 +192,10 @@ module ActiveStorage
|
|
192
192
|
# has_many_attached :photos, service: ->(gallery) { gallery.personal? ? :personal_s3 : :s3 }
|
193
193
|
# end
|
194
194
|
#
|
195
|
+
# To avoid N+1 queries, you can include the attached blobs in your query like so:
|
196
|
+
#
|
197
|
+
# Gallery.where(user: Current.user).with_attached_photos
|
198
|
+
#
|
195
199
|
# If you need to enable +strict_loading+ to prevent lazy loading of attachments,
|
196
200
|
# pass the +:strict_loading+ option. You can do:
|
197
201
|
#
|
@@ -15,6 +15,13 @@ module ActiveStorage
|
|
15
15
|
attr_reader :client, :container, :signer
|
16
16
|
|
17
17
|
def initialize(storage_account_name:, storage_access_key:, container:, public: false, **options)
|
18
|
+
ActiveStorage.deprecator.warn <<~MSG.squish
|
19
|
+
`ActiveStorage::Service::AzureStorageService` is deprecated and will be
|
20
|
+
removed in Rails 8.1.
|
21
|
+
Please try the `azure-blob` gem instead.
|
22
|
+
This gem is not maintained by the Rails team, so please test your applications before deploying to production.
|
23
|
+
MSG
|
24
|
+
|
18
25
|
@client = Azure::Storage::Blob::BlobService.create(storage_account_name: storage_account_name, storage_access_key: storage_access_key, **options)
|
19
26
|
@signer = Azure::Storage::Common::Core::Auth::SharedAccessSignature.new(storage_account_name, storage_access_key)
|
20
27
|
@container = container
|
@@ -30,6 +30,13 @@ module ActiveStorage
|
|
30
30
|
|
31
31
|
def initialize(primary:, mirrors:)
|
32
32
|
@primary, @mirrors = primary, mirrors
|
33
|
+
@executor = Concurrent::ThreadPoolExecutor.new(
|
34
|
+
min_threads: 1,
|
35
|
+
max_threads: mirrors.size,
|
36
|
+
max_queue: 0,
|
37
|
+
fallback_policy: :caller_runs,
|
38
|
+
idle_time: 60
|
39
|
+
)
|
33
40
|
end
|
34
41
|
|
35
42
|
# Upload the +io+ to the +key+ specified to all services. The upload to the primary service is done synchronously
|
@@ -75,10 +82,12 @@ module ActiveStorage
|
|
75
82
|
end
|
76
83
|
|
77
84
|
def perform_across_services(method, *args)
|
78
|
-
|
79
|
-
|
80
|
-
|
85
|
+
tasks = each_service.collect do |service|
|
86
|
+
Concurrent::Promise.execute(executor: @executor) do
|
87
|
+
service.public_send method, *args
|
88
|
+
end
|
81
89
|
end
|
90
|
+
tasks.each(&:value!)
|
82
91
|
end
|
83
92
|
end
|
84
93
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activestorage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 8.0.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-09-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,56 +16,56 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 8.0.0.beta1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 8.0.0.beta1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: actionpack
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 8.0.0.beta1
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 8.0.0.beta1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: activejob
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - '='
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 8.0.0.beta1
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - '='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 8.0.0.beta1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: activerecord
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - '='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 8.0.0.beta1
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 8.0.0.beta1
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: marcel
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -190,10 +190,10 @@ licenses:
|
|
190
190
|
- MIT
|
191
191
|
metadata:
|
192
192
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
193
|
-
changelog_uri: https://github.com/rails/rails/blob/
|
194
|
-
documentation_uri: https://api.rubyonrails.org/
|
193
|
+
changelog_uri: https://github.com/rails/rails/blob/v8.0.0.beta1/activestorage/CHANGELOG.md
|
194
|
+
documentation_uri: https://api.rubyonrails.org/v8.0.0.beta1/
|
195
195
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
196
|
-
source_code_uri: https://github.com/rails/rails/tree/
|
196
|
+
source_code_uri: https://github.com/rails/rails/tree/v8.0.0.beta1/activestorage
|
197
197
|
rubygems_mfa_required: 'true'
|
198
198
|
post_install_message:
|
199
199
|
rdoc_options: []
|
@@ -203,7 +203,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
203
203
|
requirements:
|
204
204
|
- - ">="
|
205
205
|
- !ruby/object:Gem::Version
|
206
|
-
version: 3.
|
206
|
+
version: 3.2.0
|
207
207
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
208
208
|
requirements:
|
209
209
|
- - ">="
|