activestorage 7.0.8 → 7.1.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +188 -271
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +6 -6
  5. data/app/assets/javascripts/activestorage.esm.js +11 -7
  6. data/app/assets/javascripts/activestorage.js +12 -6
  7. data/app/controllers/active_storage/blobs/proxy_controller.rb +1 -0
  8. data/app/controllers/active_storage/disk_controller.rb +4 -2
  9. data/app/controllers/active_storage/representations/proxy_controller.rb +2 -1
  10. data/app/controllers/concerns/active_storage/disable_session.rb +12 -0
  11. data/app/controllers/concerns/active_storage/file_server.rb +4 -1
  12. data/app/javascript/activestorage/blob_record.js +4 -1
  13. data/app/javascript/activestorage/direct_upload.js +3 -2
  14. data/app/javascript/activestorage/index.js +3 -1
  15. data/app/javascript/activestorage/ujs.js +3 -3
  16. data/app/jobs/active_storage/analyze_job.rb +1 -1
  17. data/app/jobs/active_storage/mirror_job.rb +1 -1
  18. data/app/jobs/active_storage/purge_job.rb +1 -1
  19. data/app/jobs/active_storage/transform_job.rb +12 -0
  20. data/app/models/active_storage/attachment.rb +90 -15
  21. data/app/models/active_storage/blob/analyzable.rb +4 -3
  22. data/app/models/active_storage/blob/identifiable.rb +1 -0
  23. data/app/models/active_storage/blob/representable.rb +7 -3
  24. data/app/models/active_storage/blob/servable.rb +22 -0
  25. data/app/models/active_storage/blob.rb +31 -67
  26. data/app/models/active_storage/current.rb +0 -10
  27. data/app/models/active_storage/filename.rb +2 -0
  28. data/app/models/active_storage/named_variant.rb +21 -0
  29. data/app/models/active_storage/preview.rb +11 -4
  30. data/app/models/active_storage/variant.rb +10 -7
  31. data/app/models/active_storage/variant_record.rb +0 -2
  32. data/app/models/active_storage/variant_with_record.rb +21 -7
  33. data/app/models/active_storage/variation.rb +5 -3
  34. data/config/routes.rb +6 -4
  35. data/db/migrate/20170806125915_create_active_storage_tables.rb +1 -1
  36. data/lib/active_storage/analyzer/audio_analyzer.rb +16 -4
  37. data/lib/active_storage/analyzer/image_analyzer.rb +2 -0
  38. data/lib/active_storage/analyzer/video_analyzer.rb +3 -1
  39. data/lib/active_storage/analyzer.rb +2 -0
  40. data/lib/active_storage/attached/changes/create_many.rb +8 -3
  41. data/lib/active_storage/attached/changes/create_one.rb +45 -3
  42. data/lib/active_storage/attached/many.rb +5 -4
  43. data/lib/active_storage/attached/model.rb +72 -43
  44. data/lib/active_storage/attached/one.rb +5 -4
  45. data/lib/active_storage/attached.rb +2 -0
  46. data/lib/active_storage/deprecator.rb +7 -0
  47. data/lib/active_storage/engine.rb +11 -7
  48. data/lib/active_storage/fixture_set.rb +7 -1
  49. data/lib/active_storage/gem_version.rb +4 -4
  50. data/lib/active_storage/log_subscriber.rb +12 -0
  51. data/lib/active_storage/previewer.rb +8 -1
  52. data/lib/active_storage/reflection.rb +3 -3
  53. data/lib/active_storage/service/azure_storage_service.rb +2 -0
  54. data/lib/active_storage/service/disk_service.rb +2 -0
  55. data/lib/active_storage/service/gcs_service.rb +11 -20
  56. data/lib/active_storage/service/mirror_service.rb +10 -5
  57. data/lib/active_storage/service/s3_service.rb +2 -0
  58. data/lib/active_storage/service.rb +4 -2
  59. data/lib/active_storage/transformers/transformer.rb +2 -0
  60. data/lib/active_storage/version.rb +1 -1
  61. data/lib/active_storage.rb +19 -3
  62. metadata +19 -28
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveStorage
4
+ # = Active Storage \Attached \Many
5
+ #
4
6
  # Decorated proxy object representing of multiple attachments to a model.
5
7
  class Attached::Many < Attached
6
8
  ##
@@ -47,12 +49,11 @@ module ActiveStorage
47
49
  # document.images.attach(io: File.open("/path/to/racecar.jpg"), filename: "racecar.jpg", content_type: "image/jpeg")
48
50
  # document.images.attach([ first_blob, second_blob ])
49
51
  def attach(*attachables)
52
+ record.public_send("#{name}=", blobs + attachables.flatten)
50
53
  if record.persisted? && !record.changed?
51
- record.public_send("#{name}=", blobs + attachables.flatten)
52
- record.save
53
- else
54
- record.public_send("#{name}=", (change&.attachables || blobs) + attachables.flatten)
54
+ return if !record.save
55
55
  end
56
+ record.public_send("#{name}")
56
57
  end
57
58
 
58
59
  # Returns true if any attachments have been made.
@@ -3,10 +3,54 @@
3
3
  require "active_support/core_ext/object/try"
4
4
 
5
5
  module ActiveStorage
6
+ # = Active Storage \Attached \Model
7
+ #
6
8
  # Provides the class-level DSL for declaring an Active Record model's attachments.
7
9
  module Attached::Model
8
10
  extend ActiveSupport::Concern
9
11
 
12
+ ##
13
+ # :method: *_attachment
14
+ #
15
+ # Returns the attachment for the +has_one_attached+.
16
+ #
17
+ # User.last.avatar_attachment
18
+
19
+ ##
20
+ # :method: *_attachments
21
+ #
22
+ # Returns the attachments for the +has_many_attached+.
23
+ #
24
+ # Gallery.last.photos_attachments
25
+
26
+ ##
27
+ # :method: *_blob
28
+ #
29
+ # Returns the blob for the +has_one_attached+ attachment.
30
+ #
31
+ # User.last.avatar_blob
32
+
33
+ ##
34
+ # :method: *_blobs
35
+ #
36
+ # Returns the blobs for the +has_many_attached+ attachments.
37
+ #
38
+ # Gallery.last.photos_blobs
39
+
40
+ ##
41
+ # :method: with_attached_*
42
+ #
43
+ # Includes the attached blobs in your query to avoid N+1 queries.
44
+ #
45
+ # If +ActiveStorage.track_variants+ is enabled, it will also include the
46
+ # variants record and their attached blobs.
47
+ #
48
+ # User.with_attached_avatar
49
+ #
50
+ # Use the plural form for +has_many_attached+:
51
+ #
52
+ # Gallery.with_attached_photos
53
+
10
54
  class_methods do
11
55
  # Specifies the relation between a single attachment and the model.
12
56
  #
@@ -59,7 +103,7 @@ module ActiveStorage
59
103
 
60
104
  def #{name}=(attachable)
61
105
  attachment_changes["#{name}"] =
62
- if attachable.nil?
106
+ if attachable.nil? || attachable == ""
63
107
  ActiveStorage::Attached::Changes::DeleteOne.new("#{name}", self)
64
108
  else
65
109
  ActiveStorage::Attached::Changes::CreateOne.new("#{name}", self, attachable)
@@ -70,7 +114,16 @@ module ActiveStorage
70
114
  has_one :"#{name}_attachment", -> { where(name: name) }, class_name: "ActiveStorage::Attachment", as: :record, inverse_of: :record, dependent: :destroy, strict_loading: strict_loading
71
115
  has_one :"#{name}_blob", through: :"#{name}_attachment", class_name: "ActiveStorage::Blob", source: :blob, strict_loading: strict_loading
72
116
 
73
- scope :"with_attached_#{name}", -> { includes("#{name}_attachment": :blob) }
117
+ scope :"with_attached_#{name}", -> {
118
+ if ActiveStorage.track_variants
119
+ includes("#{name}_attachment": { blob: {
120
+ variant_records: { image_attachment: :blob },
121
+ preview_image_attachment: { blob: { variant_records: { image_attachment: :blob } } }
122
+ } })
123
+ else
124
+ includes("#{name}_attachment": :blob)
125
+ end
126
+ }
74
127
 
75
128
  after_save { attachment_changes[name.to_s]&.save }
76
129
 
@@ -138,57 +191,25 @@ module ActiveStorage
138
191
 
139
192
  def #{name}=(attachables)
140
193
  attachables = Array(attachables).compact_blank
194
+ pending_uploads = attachment_changes["#{name}"].try(:pending_uploads)
141
195
 
142
- if ActiveStorage.replace_on_assign_to_many
143
- attachment_changes["#{name}"] =
144
- if attachables.none?
145
- ActiveStorage::Attached::Changes::DeleteMany.new("#{name}", self)
146
- else
147
- ActiveStorage::Attached::Changes::CreateMany.new("#{name}", self, attachables)
148
- end
196
+ attachment_changes["#{name}"] = if attachables.none?
197
+ ActiveStorage::Attached::Changes::DeleteMany.new("#{name}", self)
149
198
  else
150
- ActiveSupport::Deprecation.warn \
151
- "config.active_storage.replace_on_assign_to_many is deprecated and will be removed in Rails 7.1. " \
152
- "Make sure that your code works well with config.active_storage.replace_on_assign_to_many set to true before upgrading. " \
153
- "To append new attachables to the Active Storage association, prefer using `attach`. " \
154
- "Using association setter would result in purging the existing attached attachments and replacing them with new ones."
155
-
156
- if attachables.any?
157
- attachment_changes["#{name}"] =
158
- ActiveStorage::Attached::Changes::CreateMany.new("#{name}", self, #{name}.blobs + attachables)
159
- end
199
+ ActiveStorage::Attached::Changes::CreateMany.new("#{name}", self, attachables, pending_uploads: pending_uploads)
160
200
  end
161
201
  end
162
202
  CODE
163
203
 
164
- has_many :"#{name}_attachments", -> { where(name: name) }, as: :record, class_name: "ActiveStorage::Attachment", inverse_of: :record, dependent: :destroy, strict_loading: strict_loading do
165
- def purge
166
- deprecate(:purge)
167
- each(&:purge)
168
- reset
169
- end
170
-
171
- def purge_later
172
- deprecate(:purge_later)
173
- each(&:purge_later)
174
- reset
175
- end
176
-
177
- private
178
- def deprecate(action)
179
- reflection_name = proxy_association.reflection.name
180
- attached_name = reflection_name.to_s.partition("_").first
181
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
182
- Calling `#{action}` from `#{reflection_name}` is deprecated and will be removed in Rails 7.1.
183
- To migrate to Rails 7.1's behavior call `#{action}` from `#{attached_name}` instead: `#{attached_name}.#{action}`.
184
- MSG
185
- end
186
- end
204
+ has_many :"#{name}_attachments", -> { where(name: name) }, as: :record, class_name: "ActiveStorage::Attachment", inverse_of: :record, dependent: :destroy, strict_loading: strict_loading
187
205
  has_many :"#{name}_blobs", through: :"#{name}_attachments", class_name: "ActiveStorage::Blob", source: :blob, strict_loading: strict_loading
188
206
 
189
207
  scope :"with_attached_#{name}", -> {
190
208
  if ActiveStorage.track_variants
191
- includes("#{name}_attachments": { blob: :variant_records })
209
+ includes("#{name}_attachments": { blob: {
210
+ variant_records: { image_attachment: :blob },
211
+ preview_image_attachment: { blob: { variant_records: { image_attachment: :blob } } }
212
+ } })
192
213
  else
193
214
  includes("#{name}_attachments": :blob)
194
215
  end
@@ -215,6 +236,14 @@ module ActiveStorage
215
236
  ActiveStorage::Blob.services.fetch(service) do
216
237
  raise ArgumentError, "Cannot configure service :#{service} for #{name}##{association_name}"
217
238
  end
239
+ else
240
+ validate_global_service_configuration
241
+ end
242
+ end
243
+
244
+ def validate_global_service_configuration
245
+ if connected? && ActiveStorage::Blob.table_exists? && Rails.configuration.active_storage.service.nil?
246
+ raise RuntimeError, "Missing Active Storage service name. Specify Active Storage service name for config.active_storage.service in config/environments/#{Rails.env}.rb"
218
247
  end
219
248
  end
220
249
  end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveStorage
4
+ # = Active Storage \Attached \One
5
+ #
4
6
  # Representation of a single attachment to a model.
5
7
  class Attached::One < Attached
6
8
  ##
@@ -54,12 +56,11 @@ module ActiveStorage
54
56
  # person.avatar.attach(io: File.open("/path/to/face.jpg"), filename: "face.jpg", content_type: "image/jpeg")
55
57
  # person.avatar.attach(avatar_blob) # ActiveStorage::Blob object
56
58
  def attach(attachable)
59
+ record.public_send("#{name}=", attachable)
57
60
  if record.persisted? && !record.changed?
58
- record.public_send("#{name}=", attachable)
59
- record.save
60
- else
61
- record.public_send("#{name}=", attachable)
61
+ return if !record.save
62
62
  end
63
+ record.public_send("#{name}")
63
64
  end
64
65
 
65
66
  # Returns +true+ if an attachment has been made.
@@ -3,6 +3,8 @@
3
3
  require "active_support/core_ext/module/delegation"
4
4
 
5
5
  module ActiveStorage
6
+ # = Active Storage \Attached
7
+ #
6
8
  # Abstract base class for the concrete ActiveStorage::Attached::One and ActiveStorage::Attached::Many
7
9
  # classes that both provide proxy access to the blob association for a record.
8
10
  class Attached
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveStorage
4
+ def self.deprecator # :nodoc:
5
+ @deprecator ||= ActiveSupport::Deprecation.new
6
+ end
7
+ end
@@ -35,9 +35,7 @@ module ActiveStorage
35
35
  config.active_storage.variable_content_types = %w(
36
36
  image/png
37
37
  image/gif
38
- image/jpg
39
38
  image/jpeg
40
- image/pjpeg
41
39
  image/tiff
42
40
  image/bmp
43
41
  image/vnd.adobe.photoshop
@@ -51,13 +49,11 @@ module ActiveStorage
51
49
  config.active_storage.web_image_content_types = %w(
52
50
  image/png
53
51
  image/jpeg
54
- image/jpg
55
52
  image/gif
56
53
  )
57
54
 
58
55
  config.active_storage.content_types_to_serve_as_binary = %w(
59
56
  text/html
60
- text/javascript
61
57
  image/svg+xml
62
58
  application/postscript
63
59
  application/x-shockwave-flash
@@ -71,7 +67,6 @@ module ActiveStorage
71
67
  config.active_storage.content_types_allowed_inline = %w(
72
68
  image/png
73
69
  image/gif
74
- image/jpg
75
70
  image/jpeg
76
71
  image/tiff
77
72
  image/bmp
@@ -82,6 +77,10 @@ module ActiveStorage
82
77
 
83
78
  config.eager_load_namespaces << ActiveStorage
84
79
 
80
+ initializer "active_storage.deprecator", before: :load_environment_config do |app|
81
+ app.deprecators[:active_storage] = ActiveStorage.deprecator
82
+ end
83
+
85
84
  initializer "active_storage.configs" do
86
85
  config.after_initialize do |app|
87
86
  ActiveStorage.logger = app.config.active_storage.logger || Rails.logger
@@ -117,9 +116,14 @@ module ActiveStorage
117
116
  ActiveStorage.binary_content_type = app.config.active_storage.binary_content_type || "application/octet-stream"
118
117
  ActiveStorage.video_preview_arguments = app.config.active_storage.video_preview_arguments || "-y -vframes 1 -f image2"
119
118
 
120
- ActiveStorage.silence_invalid_content_types_warning = app.config.active_storage.silence_invalid_content_types_warning || false
119
+ unless app.config.active_storage.silence_invalid_content_types_warning.nil?
120
+ ActiveStorage.silence_invalid_content_types_warning = app.config.active_storage.silence_invalid_content_types_warning
121
+ end
122
+
123
+ unless app.config.active_storage.replace_on_assign_to_many.nil?
124
+ ActiveStorage.replace_on_assign_to_many = app.config.active_storage.replace_on_assign_to_many
125
+ end
121
126
 
122
- ActiveStorage.replace_on_assign_to_many = app.config.active_storage.replace_on_assign_to_many || false
123
127
  ActiveStorage.track_variants = app.config.active_storage.track_variants || false
124
128
  end
125
129
  end
@@ -4,6 +4,8 @@ require "active_support/testing/file_fixtures"
4
4
  require "active_record/secure_token"
5
5
 
6
6
  module ActiveStorage
7
+ # = Active Storage \FixtureSet
8
+ #
7
9
  # Fixtures are a way of organizing data that you want to test against; in
8
10
  # short, sample data.
9
11
  #
@@ -24,9 +26,13 @@ module ActiveStorage
24
26
  # has_one_attached :thumbnail
25
27
  # end
26
28
  #
29
+ # <code></code>
30
+ #
27
31
  # # fixtures/active_storage/blobs.yml
28
32
  # first_thumbnail_blob: <%= ActiveStorage::FixtureSet.blob filename: "first.png" %>
29
33
  #
34
+ # <code></code>
35
+ #
30
36
  # # fixtures/active_storage/attachments.yml
31
37
  # first_thumbnail_attachment:
32
38
  # name: thumbnail
@@ -46,7 +52,7 @@ module ActiveStorage
46
52
  #
47
53
  # === Examples
48
54
  #
49
- # # tests/fixtures/action_text/blobs.yml
55
+ # # tests/fixtures/active_storage/blobs.yml
50
56
  # second_thumbnail_blob: <%= ActiveStorage::FixtureSet.blob(
51
57
  # filename: "second.svg",
52
58
  # ) %>
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveStorage
4
- # Returns the currently loaded version of Active Storage as a <tt>Gem::Version</tt>.
4
+ # Returns the currently loaded version of Active Storage as a +Gem::Version+.
5
5
  def self.gem_version
6
6
  Gem::Version.new VERSION::STRING
7
7
  end
8
8
 
9
9
  module VERSION
10
10
  MAJOR = 7
11
- MINOR = 0
12
- TINY = 8
13
- PRE = nil
11
+ MINOR = 1
12
+ TINY = 3
13
+ PRE = "2"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -9,34 +9,46 @@ module ActiveStorage
9
9
  message += " (checksum: #{event.payload[:checksum]})" if event.payload[:checksum]
10
10
  info event, color(message, GREEN)
11
11
  end
12
+ subscribe_log_level :service_upload, :info
12
13
 
13
14
  def service_download(event)
14
15
  info event, color("Downloaded file from key: #{key_in(event)}", BLUE)
15
16
  end
17
+ subscribe_log_level :service_download, :info
16
18
 
17
19
  alias_method :service_streaming_download, :service_download
18
20
 
21
+ def preview(event)
22
+ info event, color("Previewed file from key: #{key_in(event)}", BLUE)
23
+ end
24
+ subscribe_log_level :preview, :info
25
+
19
26
  def service_delete(event)
20
27
  info event, color("Deleted file from key: #{key_in(event)}", RED)
21
28
  end
29
+ subscribe_log_level :service_delete, :info
22
30
 
23
31
  def service_delete_prefixed(event)
24
32
  info event, color("Deleted files by key prefix: #{event.payload[:prefix]}", RED)
25
33
  end
34
+ subscribe_log_level :service_delete_prefixed, :info
26
35
 
27
36
  def service_exist(event)
28
37
  debug event, color("Checked if file exists at key: #{key_in(event)} (#{event.payload[:exist] ? "yes" : "no"})", BLUE)
29
38
  end
39
+ subscribe_log_level :service_exist, :debug
30
40
 
31
41
  def service_url(event)
32
42
  debug event, color("Generated URL for file at key: #{key_in(event)} (#{event.payload[:url]})", BLUE)
33
43
  end
44
+ subscribe_log_level :service_url, :debug
34
45
 
35
46
  def service_mirror(event)
36
47
  message = "Mirrored file at key: #{key_in(event)}"
37
48
  message += " (checksum: #{event.payload[:checksum]})" if event.payload[:checksum]
38
49
  debug event, color(message, GREEN)
39
50
  end
51
+ subscribe_log_level :service_mirror, :debug
40
52
 
41
53
  def logger
42
54
  ActiveStorage.logger
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveStorage
4
+ # = Active Storage \Previewer
5
+ #
4
6
  # This is an abstract base class for previewers, which generate images from blobs. See
5
7
  # ActiveStorage::Previewer::MuPDFPreviewer and ActiveStorage::Previewer::VideoPreviewer for
6
8
  # examples of concrete subclasses.
@@ -65,7 +67,12 @@ module ActiveStorage
65
67
  end
66
68
 
67
69
  def instrument(operation, payload = {}, &block)
68
- ActiveSupport::Notifications.instrument "#{operation}.active_storage", payload, &block
70
+ ActiveSupport::Notifications.instrument "#{operation}.active_storage", payload.merge(service: service_name), &block
71
+ end
72
+
73
+ def service_name
74
+ # ActiveStorage::Service::DiskService => Disk
75
+ blob.service.class.to_s.split("::").third.remove("Service")
69
76
  end
70
77
 
71
78
  def capture(*argv, to:)
@@ -4,11 +4,11 @@ module ActiveStorage
4
4
  module Reflection
5
5
  class HasAttachedReflection < ActiveRecord::Reflection::MacroReflection # :nodoc:
6
6
  def variant(name, transformations)
7
- variants[name] = transformations
7
+ named_variants[name] = NamedVariant.new(transformations)
8
8
  end
9
9
 
10
- def variants
11
- @variants ||= {}
10
+ def named_variants
11
+ @named_variants ||= {}
12
12
  end
13
13
  end
14
14
 
@@ -7,6 +7,8 @@ require "azure/storage/blob"
7
7
  require "azure/storage/common/core/auth/shared_access_signature"
8
8
 
9
9
  module ActiveStorage
10
+ # = Active Storage \Azure Storage \Service
11
+ #
10
12
  # Wraps the Microsoft Azure Storage Blob Service as an Active Storage service.
11
13
  # See ActiveStorage::Service for the generic API documentation that applies to all services.
12
14
  class Service::AzureStorageService < Service
@@ -6,6 +6,8 @@ require "openssl"
6
6
  require "active_support/core_ext/numeric/bytes"
7
7
 
8
8
  module ActiveStorage
9
+ # = Active Storage \Disk \Service
10
+ #
9
11
  # Wraps a local disk path as an Active Storage service. See ActiveStorage::Service for the generic API
10
12
  # documentation that applies to all services.
11
13
  class Service::DiskService < Service
@@ -5,6 +5,8 @@ require "google/apis/iamcredentials_v1"
5
5
  require "google/cloud/storage"
6
6
 
7
7
  module ActiveStorage
8
+ # = Active Storage \GCS \Service
9
+ #
8
10
  # Wraps the Google Cloud Storage as an Active Storage service. See ActiveStorage::Service for the generic API
9
11
  # documentation that applies to all services.
10
12
  class Service::GCSService < Service
@@ -195,26 +197,15 @@ module ActiveStorage
195
197
  end
196
198
 
197
199
  def issuer
198
- @issuer ||= if @config[:gsa_email]
199
- @config[:gsa_email]
200
- else
201
- uri = URI.parse("http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email")
202
- http = Net::HTTP.new(uri.host, uri.port)
203
- request = Net::HTTP::Get.new(uri.request_uri)
204
- request["Metadata-Flavor"] = "Google"
205
-
206
- begin
207
- response = http.request(request)
208
- rescue SocketError
209
- raise MetadataServerNotFoundError
210
- end
211
-
212
- if response.is_a?(Net::HTTPSuccess)
213
- response.body
214
- else
215
- raise MetadataServerError
216
- end
217
- end
200
+ @issuer ||= @config[:gsa_email].presence || email_from_metadata_server
201
+ end
202
+
203
+ def email_from_metadata_server
204
+ env = Google::Cloud.env
205
+ raise MetadataServerNotFoundError if !env.metadata?
206
+
207
+ email = env.lookup_metadata("instance", "service-accounts/default/email")
208
+ email.presence or raise MetadataServerError
218
209
  end
219
210
 
220
211
  def signer
@@ -3,6 +3,8 @@
3
3
  require "active_support/core_ext/module/delegation"
4
4
 
5
5
  module ActiveStorage
6
+ # = Active Storage Mirror \Service
7
+ #
6
8
  # Wraps a set of mirror services and provides a single ActiveStorage::Service object that will all
7
9
  # have the files uploaded to them. A +primary+ service is designated to answer calls to:
8
10
  # * +download+
@@ -30,13 +32,13 @@ module ActiveStorage
30
32
  @primary, @mirrors = primary, mirrors
31
33
  end
32
34
 
33
- # Upload the +io+ to the +key+ specified to all services. If a +checksum+ is provided, all services will
35
+ # Upload the +io+ to the +key+ specified to all services. The upload to the primary service is done synchronously
36
+ # whereas the upload to the mirrors is done asynchronously. If a +checksum+ is provided, all services will
34
37
  # ensure a match when the upload has completed or raise an ActiveStorage::IntegrityError.
35
38
  def upload(key, io, checksum: nil, **options)
36
- each_service.collect do |service|
37
- io.rewind
38
- service.upload key, io, checksum: checksum, **options
39
- end
39
+ io.rewind
40
+ primary.upload key, io, checksum: checksum, **options
41
+ mirror_later key, checksum: checksum
40
42
  end
41
43
 
42
44
  # Delete the file at the +key+ on all services.
@@ -49,6 +51,9 @@ module ActiveStorage
49
51
  perform_across_services :delete_prefixed, prefix
50
52
  end
51
53
 
54
+ def mirror_later(key, checksum:) # :nodoc:
55
+ ActiveStorage::MirrorJob.perform_later key, checksum: checksum
56
+ end
52
57
 
53
58
  # Copy the file at the +key+ from the primary service to each of the mirrors where it doesn't already exist.
54
59
  def mirror(key, checksum:)
@@ -6,6 +6,8 @@ require "aws-sdk-s3"
6
6
  require "active_support/core_ext/numeric/bytes"
7
7
 
8
8
  module ActiveStorage
9
+ # = Active Storage \S3 \Service
10
+ #
9
11
  # Wraps the Amazon Simple Storage Service (S3) as an Active Storage service.
10
12
  # See ActiveStorage::Service for the generic API documentation that applies to all services.
11
13
  class Service::S3Service < Service
@@ -6,6 +6,8 @@ require "action_dispatch"
6
6
  require "action_dispatch/http/content_disposition"
7
7
 
8
8
  module ActiveStorage
9
+ # = Active Storage \Service
10
+ #
9
11
  # Abstract class serving as an interface for concrete services.
10
12
  #
11
13
  # The available services are:
@@ -16,7 +18,7 @@ module ActiveStorage
16
18
  # * +AzureStorage+, to manage attachments through Microsoft Azure Storage.
17
19
  # * +Mirror+, to be able to use several services to manage attachments.
18
20
  #
19
- # Inside a Rails application, you can set-up your services through the
21
+ # Inside a \Rails application, you can set-up your services through the
20
22
  # generated <tt>config/storage.yml</tt> file and reference one
21
23
  # of the aforementioned constant under the +service+ key. For example:
22
24
  #
@@ -31,7 +33,7 @@ module ActiveStorage
31
33
  #
32
34
  # config.active_storage.service = :local
33
35
  #
34
- # If you are using Active Storage outside of a Ruby on Rails application, you
36
+ # If you are using Active Storage outside of a Ruby on \Rails application, you
35
37
  # can configure the service to use like this:
36
38
  #
37
39
  # ActiveStorage::Blob.service = ActiveStorage::Service.configure(
@@ -2,6 +2,8 @@
2
2
 
3
3
  module ActiveStorage
4
4
  module Transformers
5
+ # = Active Storage \Transformers \Transformer
6
+ #
5
7
  # A Transformer applies a set of transformations to an image.
6
8
  #
7
9
  # The following concrete subclasses are included in Active Storage:
@@ -3,7 +3,7 @@
3
3
  require_relative "gem_version"
4
4
 
5
5
  module ActiveStorage
6
- # Returns the currently loaded version of Active Storage as a <tt>Gem::Version</tt>.
6
+ # Returns the currently loaded version of Active Storage as a +Gem::Version+.
7
7
  def self.version
8
8
  gem_version
9
9
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # Copyright (c) 2017-2022 David Heinemeier Hansson, Basecamp
4
+ # Copyright (c) David Heinemeier Hansson, 37signals LLC
5
5
  #
6
6
  # Permission is hereby granted, free of charge, to any person obtaining
7
7
  # a copy of this software and associated documentation files (the
@@ -29,10 +29,13 @@ require "active_support/rails"
29
29
  require "active_support/core_ext/numeric/time"
30
30
 
31
31
  require "active_storage/version"
32
+ require "active_storage/deprecator"
32
33
  require "active_storage/errors"
33
34
 
34
35
  require "marcel"
35
36
 
37
+ # :markup: markdown
38
+ # :include: activestorage/README.md
36
39
  module ActiveStorage
37
40
  extend ActiveSupport::Autoload
38
41
 
@@ -357,12 +360,25 @@ module ActiveStorage
357
360
  mattr_accessor :draw_routes, default: true
358
361
  mattr_accessor :resolve_model_to_route, default: :rails_storage_redirect
359
362
 
360
- mattr_accessor :replace_on_assign_to_many, default: false
361
363
  mattr_accessor :track_variants, default: false
362
364
 
363
365
  mattr_accessor :video_preview_arguments, default: "-y -vframes 1 -f image2"
364
366
 
365
- mattr_accessor :silence_invalid_content_types_warning, default: false
367
+ def self.replace_on_assign_to_many
368
+ ActiveStorage.deprecator.warn("config.active_storage.replace_on_assign_to_many is deprecated and has no effect.")
369
+ end
370
+
371
+ def self.replace_on_assign_to_many=(value)
372
+ ActiveStorage.deprecator.warn("config.active_storage.replace_on_assign_to_many is deprecated and has no effect.")
373
+ end
374
+
375
+ def self.silence_invalid_content_types_warning
376
+ ActiveStorage.deprecator.warn("config.active_storage.silence_invalid_content_types_warning is deprecated and has no effect.")
377
+ end
378
+
379
+ def self.silence_invalid_content_types_warning=(value)
380
+ ActiveStorage.deprecator.warn("config.active_storage.silence_invalid_content_types_warning is deprecated and has no effect.")
381
+ end
366
382
 
367
383
  module Transformers
368
384
  extend ActiveSupport::Autoload