activestorage 6.1.7.8 → 7.0.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activestorage might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +126 -326
- data/MIT-LICENSE +1 -1
- data/README.md +25 -11
- data/app/assets/javascripts/activestorage.esm.js +844 -0
- data/app/assets/javascripts/activestorage.js +257 -376
- data/app/controllers/active_storage/base_controller.rb +1 -10
- data/app/controllers/active_storage/blobs/proxy_controller.rb +14 -5
- data/app/controllers/active_storage/blobs/redirect_controller.rb +6 -4
- data/app/controllers/active_storage/representations/base_controller.rb +5 -1
- data/app/controllers/active_storage/representations/proxy_controller.rb +6 -5
- data/app/controllers/active_storage/representations/redirect_controller.rb +6 -4
- data/app/controllers/concerns/active_storage/set_blob.rb +6 -2
- data/app/controllers/concerns/active_storage/set_current.rb +3 -3
- data/app/controllers/concerns/active_storage/streaming.rb +65 -0
- data/app/javascript/activestorage/ujs.js +1 -1
- data/app/models/active_storage/attachment.rb +35 -2
- data/app/models/active_storage/blob/representable.rb +7 -5
- data/app/models/active_storage/blob.rb +26 -27
- data/app/models/active_storage/current.rb +12 -2
- data/app/models/active_storage/preview.rb +6 -4
- data/app/models/active_storage/record.rb +1 -1
- data/app/models/active_storage/variant.rb +6 -9
- data/app/models/active_storage/variant_record.rb +2 -0
- data/app/models/active_storage/variant_with_record.rb +9 -5
- data/app/models/active_storage/variation.rb +3 -3
- data/config/routes.rb +10 -10
- data/db/migrate/20170806125915_create_active_storage_tables.rb +11 -2
- data/db/update_migrate/20190112182829_add_service_name_to_active_storage_blobs.rb +0 -4
- data/db/update_migrate/20191206030411_create_active_storage_variant_records.rb +1 -3
- data/lib/active_storage/analyzer/audio_analyzer.rb +65 -0
- data/lib/active_storage/analyzer/image_analyzer/image_magick.rb +39 -0
- data/lib/active_storage/analyzer/image_analyzer/vips.rb +49 -0
- data/lib/active_storage/analyzer/image_analyzer.rb +2 -30
- data/lib/active_storage/analyzer/video_analyzer.rb +26 -11
- data/lib/active_storage/analyzer.rb +8 -4
- data/lib/active_storage/attached/changes/create_many.rb +7 -3
- data/lib/active_storage/attached/changes/create_one.rb +1 -1
- data/lib/active_storage/attached/changes/create_one_of_many.rb +1 -1
- data/lib/active_storage/attached/changes/delete_many.rb +1 -1
- data/lib/active_storage/attached/changes/delete_one.rb +1 -1
- data/lib/active_storage/attached/changes/detach_many.rb +18 -0
- data/lib/active_storage/attached/changes/detach_one.rb +24 -0
- data/lib/active_storage/attached/changes/purge_many.rb +27 -0
- data/lib/active_storage/attached/changes/purge_one.rb +27 -0
- data/lib/active_storage/attached/changes.rb +7 -1
- data/lib/active_storage/attached/many.rb +27 -15
- data/lib/active_storage/attached/model.rb +31 -5
- data/lib/active_storage/attached/one.rb +32 -27
- data/lib/active_storage/downloader.rb +2 -2
- data/lib/active_storage/engine.rb +28 -16
- data/lib/active_storage/fixture_set.rb +76 -0
- data/lib/active_storage/gem_version.rb +4 -4
- data/lib/active_storage/previewer/video_previewer.rb +0 -2
- data/lib/active_storage/previewer.rb +4 -4
- data/lib/active_storage/reflection.rb +12 -2
- data/lib/active_storage/service/azure_storage_service.rb +1 -1
- data/lib/active_storage/service/configurator.rb +1 -1
- data/lib/active_storage/service/disk_service.rb +13 -18
- data/lib/active_storage/service/gcs_service.rb +91 -7
- data/lib/active_storage/service/mirror_service.rb +1 -1
- data/lib/active_storage/service/registry.rb +1 -1
- data/lib/active_storage/service/s3_service.rb +4 -4
- data/lib/active_storage/service.rb +3 -3
- data/lib/active_storage/transformers/image_processing_transformer.rb +1 -66
- data/lib/active_storage/transformers/transformer.rb +1 -1
- data/lib/active_storage.rb +3 -292
- metadata +32 -25
- data/app/controllers/concerns/active_storage/disable_session.rb +0 -12
- data/app/controllers/concerns/active_storage/set_headers.rb +0 -12
@@ -3,6 +3,25 @@
|
|
3
3
|
module ActiveStorage
|
4
4
|
# Decorated proxy object representing of multiple attachments to a model.
|
5
5
|
class Attached::Many < Attached
|
6
|
+
##
|
7
|
+
# :method: purge
|
8
|
+
#
|
9
|
+
# Directly purges each associated attachment (i.e. destroys the blobs and
|
10
|
+
# attachments and deletes the files on the service).
|
11
|
+
delegate :purge, to: :purge_many
|
12
|
+
|
13
|
+
##
|
14
|
+
# :method: purge_later
|
15
|
+
#
|
16
|
+
# Purges each associated attachment through the queuing system.
|
17
|
+
delegate :purge_later, to: :purge_many
|
18
|
+
|
19
|
+
##
|
20
|
+
# :method: detach
|
21
|
+
#
|
22
|
+
# Deletes associated attachments without purging them, leaving their respective blobs in place.
|
23
|
+
delegate :detach, to: :detach_many
|
24
|
+
|
6
25
|
delegate_missing_to :attachments
|
7
26
|
|
8
27
|
# Returns all the associated attachment records.
|
@@ -25,7 +44,7 @@ module ActiveStorage
|
|
25
44
|
#
|
26
45
|
# document.images.attach(params[:images]) # Array of ActionDispatch::Http::UploadedFile objects
|
27
46
|
# document.images.attach(params[:signed_blob_id]) # Signed reference to blob from direct upload
|
28
|
-
# document.images.attach(io: File.open("/path/to/racecar.jpg"), filename: "racecar.jpg", content_type: "image/
|
47
|
+
# document.images.attach(io: File.open("/path/to/racecar.jpg"), filename: "racecar.jpg", content_type: "image/jpeg")
|
29
48
|
# document.images.attach([ first_blob, second_blob ])
|
30
49
|
def attach(*attachables)
|
31
50
|
if record.persisted? && !record.changed?
|
@@ -47,20 +66,13 @@ module ActiveStorage
|
|
47
66
|
attachments.any?
|
48
67
|
end
|
49
68
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
##
|
56
|
-
# :method: purge
|
57
|
-
#
|
58
|
-
# Directly purges each associated attachment (i.e. destroys the blobs and
|
59
|
-
# attachments and deletes the files on the service).
|
69
|
+
private
|
70
|
+
def purge_many
|
71
|
+
Attached::Changes::PurgeMany.new(name, record, attachments)
|
72
|
+
end
|
60
73
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
# Purges each associated attachment through the queuing system.
|
74
|
+
def detach_many
|
75
|
+
Attached::Changes::DetachMany.new(name, record, attachments)
|
76
|
+
end
|
65
77
|
end
|
66
78
|
end
|
@@ -83,6 +83,7 @@ module ActiveStorage
|
|
83
83
|
{ dependent: dependent, service_name: service },
|
84
84
|
self
|
85
85
|
)
|
86
|
+
yield reflection if block_given?
|
86
87
|
ActiveRecord::Reflection.add_attachment_reflection(self, name, reflection)
|
87
88
|
end
|
88
89
|
|
@@ -144,6 +145,12 @@ module ActiveStorage
|
|
144
145
|
ActiveStorage::Attached::Changes::CreateMany.new("#{name}", self, attachables)
|
145
146
|
end
|
146
147
|
else
|
148
|
+
ActiveSupport::Deprecation.warn \
|
149
|
+
"config.active_storage.replace_on_assign_to_many is deprecated and will be removed in Rails 7.1. " \
|
150
|
+
"Make sure that your code works well with config.active_storage.replace_on_assign_to_many set to true before upgrading. " \
|
151
|
+
"To append new attachables to the Active Storage association, prefer using `attach`. " \
|
152
|
+
"Using association setter would result in purging the existing attached attachments and replacing them with new ones."
|
153
|
+
|
147
154
|
if Array(attachables).any?
|
148
155
|
attachment_changes["#{name}"] =
|
149
156
|
ActiveStorage::Attached::Changes::CreateMany.new("#{name}", self, #{name}.blobs + attachables)
|
@@ -154,18 +161,36 @@ module ActiveStorage
|
|
154
161
|
|
155
162
|
has_many :"#{name}_attachments", -> { where(name: name) }, as: :record, class_name: "ActiveStorage::Attachment", inverse_of: :record, dependent: :destroy, strict_loading: strict_loading do
|
156
163
|
def purge
|
164
|
+
deprecate(:purge)
|
157
165
|
each(&:purge)
|
158
166
|
reset
|
159
167
|
end
|
160
168
|
|
161
169
|
def purge_later
|
170
|
+
deprecate(:purge_later)
|
162
171
|
each(&:purge_later)
|
163
172
|
reset
|
164
173
|
end
|
174
|
+
|
175
|
+
private
|
176
|
+
def deprecate(action)
|
177
|
+
reflection_name = proxy_association.reflection.name
|
178
|
+
attached_name = reflection_name.to_s.partition("_").first
|
179
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
180
|
+
Calling `#{action}` from `#{reflection_name}` is deprecated and will be removed in Rails 7.1.
|
181
|
+
To migrate to Rails 7.1's behavior call `#{action}` from `#{attached_name}` instead: `#{attached_name}.#{action}`.
|
182
|
+
MSG
|
183
|
+
end
|
165
184
|
end
|
166
185
|
has_many :"#{name}_blobs", through: :"#{name}_attachments", class_name: "ActiveStorage::Blob", source: :blob, strict_loading: strict_loading
|
167
186
|
|
168
|
-
scope :"with_attached_#{name}", -> {
|
187
|
+
scope :"with_attached_#{name}", -> {
|
188
|
+
if ActiveStorage.track_variants
|
189
|
+
includes("#{name}_attachments": { blob: :variant_records })
|
190
|
+
else
|
191
|
+
includes("#{name}_attachments": :blob)
|
192
|
+
end
|
193
|
+
}
|
169
194
|
|
170
195
|
after_save { attachment_changes[name.to_s]&.save }
|
171
196
|
|
@@ -178,6 +203,7 @@ module ActiveStorage
|
|
178
203
|
{ dependent: dependent, service_name: service },
|
179
204
|
self
|
180
205
|
)
|
206
|
+
yield reflection if block_given?
|
181
207
|
ActiveRecord::Reflection.add_attachment_reflection(self, name, reflection)
|
182
208
|
end
|
183
209
|
|
@@ -191,21 +217,21 @@ module ActiveStorage
|
|
191
217
|
end
|
192
218
|
end
|
193
219
|
|
194
|
-
def attachment_changes
|
220
|
+
def attachment_changes # :nodoc:
|
195
221
|
@attachment_changes ||= {}
|
196
222
|
end
|
197
223
|
|
198
|
-
def changed_for_autosave?
|
224
|
+
def changed_for_autosave? # :nodoc:
|
199
225
|
super || attachment_changes.any?
|
200
226
|
end
|
201
227
|
|
202
|
-
def initialize_dup(*)
|
228
|
+
def initialize_dup(*) # :nodoc:
|
203
229
|
super
|
204
230
|
@active_storage_attached = nil
|
205
231
|
@attachment_changes = nil
|
206
232
|
end
|
207
233
|
|
208
|
-
def reload(*)
|
234
|
+
def reload(*) # :nodoc:
|
209
235
|
super.tap { @attachment_changes = nil }
|
210
236
|
end
|
211
237
|
end
|
@@ -3,6 +3,25 @@
|
|
3
3
|
module ActiveStorage
|
4
4
|
# Representation of a single attachment to a model.
|
5
5
|
class Attached::One < Attached
|
6
|
+
##
|
7
|
+
# :method: purge
|
8
|
+
#
|
9
|
+
# Directly purges the attachment (i.e. destroys the blob and
|
10
|
+
# attachment and deletes the file on the service).
|
11
|
+
delegate :purge, to: :purge_one
|
12
|
+
|
13
|
+
##
|
14
|
+
# :method: purge_later
|
15
|
+
#
|
16
|
+
# Purges the attachment through the queuing system.
|
17
|
+
delegate :purge_later, to: :purge_one
|
18
|
+
|
19
|
+
##
|
20
|
+
# :method: detach
|
21
|
+
#
|
22
|
+
# Deletes the attachment without purging it, leaving its blob in place.
|
23
|
+
delegate :detach, to: :detach_one
|
24
|
+
|
6
25
|
delegate_missing_to :attachment, allow_nil: true
|
7
26
|
|
8
27
|
# Returns the associated attachment record.
|
@@ -13,6 +32,13 @@ module ActiveStorage
|
|
13
32
|
change.present? ? change.attachment : record.public_send("#{name}_attachment")
|
14
33
|
end
|
15
34
|
|
35
|
+
# Returns +true+ if an attachment is not attached.
|
36
|
+
#
|
37
|
+
# class User < ApplicationRecord
|
38
|
+
# has_one_attached :avatar
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# User.new.avatar.blank? # => true
|
16
42
|
def blank?
|
17
43
|
!attached?
|
18
44
|
end
|
@@ -25,7 +51,7 @@ module ActiveStorage
|
|
25
51
|
#
|
26
52
|
# person.avatar.attach(params[:avatar]) # ActionDispatch::Http::UploadedFile object
|
27
53
|
# person.avatar.attach(params[:signed_blob_id]) # Signed reference to blob from direct upload
|
28
|
-
# person.avatar.attach(io: File.open("/path/to/face.jpg"), filename: "face.jpg", content_type: "image/
|
54
|
+
# person.avatar.attach(io: File.open("/path/to/face.jpg"), filename: "face.jpg", content_type: "image/jpeg")
|
29
55
|
# person.avatar.attach(avatar_blob) # ActiveStorage::Blob object
|
30
56
|
def attach(attachable)
|
31
57
|
if record.persisted? && !record.changed?
|
@@ -47,34 +73,13 @@ module ActiveStorage
|
|
47
73
|
attachment.present?
|
48
74
|
end
|
49
75
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
attachment.delete
|
54
|
-
write_attachment nil
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
# Directly purges the attachment (i.e. destroys the blob and
|
59
|
-
# attachment and deletes the file on the service).
|
60
|
-
def purge
|
61
|
-
if attached?
|
62
|
-
attachment.purge
|
63
|
-
write_attachment nil
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
# Purges the attachment through the queuing system.
|
68
|
-
def purge_later
|
69
|
-
if attached?
|
70
|
-
attachment.purge_later
|
71
|
-
write_attachment nil
|
76
|
+
private
|
77
|
+
def purge_one
|
78
|
+
Attached::Changes::PurgeOne.new(name, record, attachment)
|
72
79
|
end
|
73
|
-
end
|
74
80
|
|
75
|
-
|
76
|
-
|
77
|
-
record.public_send("#{name}_attachment=", attachment)
|
81
|
+
def detach_one
|
82
|
+
Attached::Changes::DetachOne.new(name, record, attachment)
|
78
83
|
end
|
79
84
|
end
|
80
85
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveStorage
|
4
|
-
class Downloader
|
4
|
+
class Downloader # :nodoc:
|
5
5
|
attr_reader :service
|
6
6
|
|
7
7
|
def initialize(service)
|
@@ -35,7 +35,7 @@ module ActiveStorage
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def verify_integrity_of(file, checksum:)
|
38
|
-
unless Digest::MD5.file(file).base64digest == checksum
|
38
|
+
unless OpenSSL::Digest::MD5.file(file).base64digest == checksum
|
39
39
|
raise ActiveStorage::IntegrityError
|
40
40
|
end
|
41
41
|
end
|
@@ -12,7 +12,10 @@ require "active_storage/previewer/mupdf_previewer"
|
|
12
12
|
require "active_storage/previewer/video_previewer"
|
13
13
|
|
14
14
|
require "active_storage/analyzer/image_analyzer"
|
15
|
+
require "active_storage/analyzer/image_analyzer/image_magick"
|
16
|
+
require "active_storage/analyzer/image_analyzer/vips"
|
15
17
|
require "active_storage/analyzer/video_analyzer"
|
18
|
+
require "active_storage/analyzer/audio_analyzer"
|
16
19
|
|
17
20
|
require "active_storage/service/registry"
|
18
21
|
|
@@ -24,7 +27,7 @@ module ActiveStorage
|
|
24
27
|
|
25
28
|
config.active_storage = ActiveSupport::OrderedOptions.new
|
26
29
|
config.active_storage.previewers = [ ActiveStorage::Previewer::PopplerPDFPreviewer, ActiveStorage::Previewer::MuPDFPreviewer, ActiveStorage::Previewer::VideoPreviewer ]
|
27
|
-
config.active_storage.analyzers = [ ActiveStorage::Analyzer::ImageAnalyzer, ActiveStorage::Analyzer::VideoAnalyzer ]
|
30
|
+
config.active_storage.analyzers = [ ActiveStorage::Analyzer::ImageAnalyzer::Vips, ActiveStorage::Analyzer::ImageAnalyzer::ImageMagick, ActiveStorage::Analyzer::VideoAnalyzer, ActiveStorage::Analyzer::AudioAnalyzer ]
|
28
31
|
config.active_storage.paths = ActiveSupport::OrderedOptions.new
|
29
32
|
config.active_storage.queues = ActiveSupport::InheritableOptions.new
|
30
33
|
|
@@ -39,6 +42,9 @@ module ActiveStorage
|
|
39
42
|
image/vnd.adobe.photoshop
|
40
43
|
image/vnd.microsoft.icon
|
41
44
|
image/webp
|
45
|
+
image/avif
|
46
|
+
image/heic
|
47
|
+
image/heif
|
42
48
|
)
|
43
49
|
|
44
50
|
config.active_storage.web_image_content_types = %w(
|
@@ -86,25 +92,11 @@ module ActiveStorage
|
|
86
92
|
ActiveStorage.draw_routes = app.config.active_storage.draw_routes != false
|
87
93
|
ActiveStorage.resolve_model_to_route = app.config.active_storage.resolve_model_to_route || :rails_storage_redirect
|
88
94
|
|
89
|
-
ActiveStorage.supported_image_processing_methods += app.config.active_storage.supported_image_processing_methods || []
|
90
|
-
ActiveStorage.unsupported_image_processing_arguments = app.config.active_storage.unsupported_image_processing_arguments || %w(
|
91
|
-
-debug
|
92
|
-
-display
|
93
|
-
-distribute-cache
|
94
|
-
-help
|
95
|
-
-path
|
96
|
-
-print
|
97
|
-
-set
|
98
|
-
-verbose
|
99
|
-
-version
|
100
|
-
-write
|
101
|
-
-write-mask
|
102
|
-
)
|
103
|
-
|
104
95
|
ActiveStorage.variable_content_types = app.config.active_storage.variable_content_types || []
|
105
96
|
ActiveStorage.web_image_content_types = app.config.active_storage.web_image_content_types || []
|
106
97
|
ActiveStorage.content_types_to_serve_as_binary = app.config.active_storage.content_types_to_serve_as_binary || []
|
107
98
|
ActiveStorage.service_urls_expire_in = app.config.active_storage.service_urls_expire_in || 5.minutes
|
99
|
+
ActiveStorage.urls_expire_in = app.config.active_storage.urls_expire_in
|
108
100
|
ActiveStorage.content_types_allowed_inline = app.config.active_storage.content_types_allowed_inline || []
|
109
101
|
ActiveStorage.binary_content_type = app.config.active_storage.binary_content_type || "application/octet-stream"
|
110
102
|
ActiveStorage.video_preview_arguments = app.config.active_storage.video_preview_arguments || "-y -vframes 1 -f image2"
|
@@ -159,5 +151,25 @@ module ActiveStorage
|
|
159
151
|
ActiveRecord::Reflection.singleton_class.prepend(Reflection::ReflectionExtension)
|
160
152
|
end
|
161
153
|
end
|
154
|
+
|
155
|
+
initializer "active_storage.asset" do
|
156
|
+
if Rails.application.config.respond_to?(:assets)
|
157
|
+
Rails.application.config.assets.precompile += %w( activestorage activestorage.esm )
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
initializer "active_storage.fixture_set" do
|
162
|
+
ActiveSupport.on_load(:active_record_fixture_set) do
|
163
|
+
ActiveStorage::FixtureSet.file_fixture_path ||= Rails.root.join(*[
|
164
|
+
ENV.fetch("FIXTURES_PATH") { File.join("test", "fixtures") },
|
165
|
+
ENV["FIXTURES_DIR"],
|
166
|
+
"files"
|
167
|
+
].compact_blank)
|
168
|
+
end
|
169
|
+
|
170
|
+
ActiveSupport.on_load(:active_support_test_case) do
|
171
|
+
ActiveStorage::FixtureSet.file_fixture_path = ActiveSupport::TestCase.file_fixture_path
|
172
|
+
end
|
173
|
+
end
|
162
174
|
end
|
163
175
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/testing/file_fixtures"
|
4
|
+
require "active_record/secure_token"
|
5
|
+
|
6
|
+
module ActiveStorage
|
7
|
+
# Fixtures are a way of organizing data that you want to test against; in
|
8
|
+
# short, sample data.
|
9
|
+
#
|
10
|
+
# To learn more about fixtures, read the
|
11
|
+
# {ActiveRecord::FixtureSet}[rdoc-ref:ActiveRecord::FixtureSet] documentation.
|
12
|
+
#
|
13
|
+
# === YAML
|
14
|
+
#
|
15
|
+
# Like other Active Record-backed models,
|
16
|
+
# {ActiveStorage::Attachment}[rdoc-ref:ActiveStorage::Attachment] and
|
17
|
+
# {ActiveStorage::Blob}[rdoc-ref:ActiveStorage::Blob] records inherit from
|
18
|
+
# {ActiveRecord::Base}[rdoc-ref:ActiveRecord::Base] instances and therefore
|
19
|
+
# can be populated by fixtures.
|
20
|
+
#
|
21
|
+
# Consider a hypothetical <tt>Article</tt> model class, its related
|
22
|
+
# fixture data, as well as fixture data for related ActiveStorage::Attachment
|
23
|
+
# and ActiveStorage::Blob records:
|
24
|
+
#
|
25
|
+
# # app/models/article.rb
|
26
|
+
# class Article < ApplicationRecord
|
27
|
+
# has_one_attached :thumbnail
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# # fixtures/active_storage/blobs.yml
|
31
|
+
# first_thumbnail_blob: <%= ActiveStorage::FixtureSet.blob filename: "first.png" %>
|
32
|
+
#
|
33
|
+
# # fixtures/active_storage/attachments.yml
|
34
|
+
# first_thumbnail_attachment:
|
35
|
+
# name: thumbnail
|
36
|
+
# record: first (Article)
|
37
|
+
# blob: first_thumbnail_blob
|
38
|
+
#
|
39
|
+
# When processed, Active Record will insert database records for each fixture
|
40
|
+
# entry and will ensure the Active Storage relationship is intact.
|
41
|
+
class FixtureSet
|
42
|
+
include ActiveSupport::Testing::FileFixtures
|
43
|
+
include ActiveRecord::SecureToken
|
44
|
+
|
45
|
+
# Generate a YAML-encoded representation of an ActiveStorage::Blob
|
46
|
+
# instance's attributes, resolve the file relative to the directory mentioned
|
47
|
+
# by <tt>ActiveSupport::Testing::FileFixtures.file_fixture</tt>, and upload
|
48
|
+
# the file to the Service
|
49
|
+
#
|
50
|
+
# === Examples
|
51
|
+
#
|
52
|
+
# # tests/fixtures/action_text/blobs.yml
|
53
|
+
# second_thumbnail_blob: <%= ActiveStorage::FixtureSet.blob(
|
54
|
+
# filename: "second.svg",
|
55
|
+
# ) %>
|
56
|
+
#
|
57
|
+
# third_thumbnail_blob: <%= ActiveStorage::FixtureSet.blob(
|
58
|
+
# filename: "third.svg",
|
59
|
+
# content_type: "image/svg+xml",
|
60
|
+
# service_name: "public"
|
61
|
+
# ) %>
|
62
|
+
#
|
63
|
+
def self.blob(filename:, **attributes)
|
64
|
+
new.prepare Blob.new(filename: filename, key: generate_unique_secure_token), **attributes
|
65
|
+
end
|
66
|
+
|
67
|
+
def prepare(instance, **attributes)
|
68
|
+
io = file_fixture(instance.filename.to_s).open
|
69
|
+
instance.unfurl(io)
|
70
|
+
instance.assign_attributes(attributes)
|
71
|
+
instance.upload_without_unfurling(io)
|
72
|
+
|
73
|
+
instance.attributes.transform_values { |value| value.is_a?(Hash) ? value.to_json : value }.compact.to_json
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -26,7 +26,7 @@ module ActiveStorage
|
|
26
26
|
|
27
27
|
private
|
28
28
|
# Downloads the blob to a tempfile on disk. Yields the tempfile.
|
29
|
-
def download_blob_to_tempfile(&block)
|
29
|
+
def download_blob_to_tempfile(&block) # :doc:
|
30
30
|
blob.open tmpdir: tmpdir, &block
|
31
31
|
end
|
32
32
|
|
@@ -44,7 +44,7 @@ module ActiveStorage
|
|
44
44
|
# end
|
45
45
|
#
|
46
46
|
# The output tempfile is opened in the directory returned by #tmpdir.
|
47
|
-
def draw(*argv)
|
47
|
+
def draw(*argv) # :doc:
|
48
48
|
open_tempfile do |file|
|
49
49
|
instrument :preview, key: blob.key do
|
50
50
|
capture(*argv, to: file)
|
@@ -83,11 +83,11 @@ module ActiveStorage
|
|
83
83
|
to.rewind
|
84
84
|
end
|
85
85
|
|
86
|
-
def logger
|
86
|
+
def logger # :doc:
|
87
87
|
ActiveStorage.logger
|
88
88
|
end
|
89
89
|
|
90
|
-
def tmpdir
|
90
|
+
def tmpdir # :doc:
|
91
91
|
Dir.tmpdir
|
92
92
|
end
|
93
93
|
end
|
@@ -2,9 +2,19 @@
|
|
2
2
|
|
3
3
|
module ActiveStorage
|
4
4
|
module Reflection
|
5
|
+
class HasAttachedReflection < ActiveRecord::Reflection::MacroReflection # :nodoc:
|
6
|
+
def variant(name, transformations)
|
7
|
+
variants[name] = transformations
|
8
|
+
end
|
9
|
+
|
10
|
+
def variants
|
11
|
+
@variants ||= {}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
5
15
|
# Holds all the metadata about a has_one_attached attachment as it was
|
6
16
|
# specified in the Active Record class.
|
7
|
-
class HasOneAttachedReflection <
|
17
|
+
class HasOneAttachedReflection < HasAttachedReflection # :nodoc:
|
8
18
|
def macro
|
9
19
|
:has_one_attached
|
10
20
|
end
|
@@ -12,7 +22,7 @@ module ActiveStorage
|
|
12
22
|
|
13
23
|
# Holds all the metadata about a has_many_attached attachment as it was
|
14
24
|
# specified in the Active Record class.
|
15
|
-
class HasManyAttachedReflection <
|
25
|
+
class HasManyAttachedReflection < HasAttachedReflection # :nodoc:
|
16
26
|
def macro
|
17
27
|
:has_many_attached
|
18
28
|
end
|
@@ -2,14 +2,14 @@
|
|
2
2
|
|
3
3
|
require "fileutils"
|
4
4
|
require "pathname"
|
5
|
-
require "
|
5
|
+
require "openssl"
|
6
6
|
require "active_support/core_ext/numeric/bytes"
|
7
7
|
|
8
8
|
module ActiveStorage
|
9
9
|
# Wraps a local disk path as an Active Storage service. See ActiveStorage::Service for the generic API
|
10
10
|
# documentation that applies to all services.
|
11
11
|
class Service::DiskService < Service
|
12
|
-
|
12
|
+
attr_accessor :root
|
13
13
|
|
14
14
|
def initialize(root:, public: false, **options)
|
15
15
|
@root = root
|
@@ -86,11 +86,9 @@ module ActiveStorage
|
|
86
86
|
purpose: :blob_token
|
87
87
|
)
|
88
88
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
generated_url
|
89
|
+
url_helpers.update_rails_disk_service_url(verified_token_with_expiration, url_options).tap do |generated_url|
|
90
|
+
payload[:url] = generated_url
|
91
|
+
end
|
94
92
|
end
|
95
93
|
end
|
96
94
|
|
@@ -98,7 +96,7 @@ module ActiveStorage
|
|
98
96
|
{ "Content-Type" => content_type }
|
99
97
|
end
|
100
98
|
|
101
|
-
def path_for(key)
|
99
|
+
def path_for(key) # :nodoc:
|
102
100
|
File.join root, folder_for(key), key
|
103
101
|
end
|
104
102
|
|
@@ -124,14 +122,11 @@ module ActiveStorage
|
|
124
122
|
purpose: :blob_key
|
125
123
|
)
|
126
124
|
|
127
|
-
|
125
|
+
if url_options.blank?
|
126
|
+
raise ArgumentError, "Cannot generate URL for #{filename} using Disk service, please set ActiveStorage::Current.url_options."
|
127
|
+
end
|
128
128
|
|
129
|
-
url_helpers.rails_disk_service_url(verified_key_with_expiration,
|
130
|
-
protocol: current_uri.scheme,
|
131
|
-
host: current_uri.host,
|
132
|
-
port: current_uri.port,
|
133
|
-
filename: filename
|
134
|
-
)
|
129
|
+
url_helpers.rails_disk_service_url(verified_key_with_expiration, filename: filename, **url_options)
|
135
130
|
end
|
136
131
|
|
137
132
|
|
@@ -154,7 +149,7 @@ module ActiveStorage
|
|
154
149
|
end
|
155
150
|
|
156
151
|
def ensure_integrity_of(key, checksum)
|
157
|
-
unless Digest::MD5.file(path_for(key)).base64digest == checksum
|
152
|
+
unless OpenSSL::Digest::MD5.file(path_for(key)).base64digest == checksum
|
158
153
|
delete key
|
159
154
|
raise ActiveStorage::IntegrityError
|
160
155
|
end
|
@@ -164,8 +159,8 @@ module ActiveStorage
|
|
164
159
|
@url_helpers ||= Rails.application.routes.url_helpers
|
165
160
|
end
|
166
161
|
|
167
|
-
def
|
168
|
-
ActiveStorage::Current.
|
162
|
+
def url_options
|
163
|
+
ActiveStorage::Current.url_options
|
169
164
|
end
|
170
165
|
end
|
171
166
|
end
|