activestorage 5.2.8 → 6.0.0.beta1

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.

Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +102 -152
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +6 -5
  5. data/app/assets/javascripts/activestorage.js +4 -1
  6. data/app/controllers/active_storage/base_controller.rb +3 -5
  7. data/app/controllers/active_storage/blobs_controller.rb +1 -1
  8. data/app/controllers/active_storage/disk_controller.rb +4 -1
  9. data/app/controllers/active_storage/representations_controller.rb +1 -1
  10. data/app/controllers/concerns/active_storage/set_current.rb +15 -0
  11. data/app/javascript/activestorage/blob_record.js +6 -1
  12. data/app/jobs/active_storage/analyze_job.rb +4 -0
  13. data/app/jobs/active_storage/base_job.rb +0 -1
  14. data/app/jobs/active_storage/purge_job.rb +3 -0
  15. data/app/models/active_storage/attachment.rb +18 -9
  16. data/app/models/active_storage/blob/representable.rb +5 -5
  17. data/app/models/active_storage/blob.rb +63 -22
  18. data/app/models/active_storage/filename.rb +0 -6
  19. data/app/models/active_storage/preview.rb +3 -3
  20. data/app/models/active_storage/variant.rb +51 -52
  21. data/app/models/active_storage/variation.rb +23 -92
  22. data/config/routes.rb +13 -12
  23. data/db/update_migrate/20180723000244_add_foreign_key_constraint_to_active_storage_attachments_for_blob_id.rb +7 -0
  24. data/lib/active_storage/analyzer/video_analyzer.rb +2 -4
  25. data/lib/active_storage/analyzer.rb +9 -4
  26. data/lib/active_storage/attached/changes/create_many.rb +46 -0
  27. data/lib/active_storage/attached/changes/create_one.rb +68 -0
  28. data/lib/active_storage/attached/changes/create_one_of_many.rb +10 -0
  29. data/lib/active_storage/attached/changes/delete_many.rb +23 -0
  30. data/lib/active_storage/attached/changes/delete_one.rb +19 -0
  31. data/lib/active_storage/attached/changes.rb +16 -0
  32. data/lib/active_storage/attached/many.rb +16 -10
  33. data/lib/active_storage/attached/model.rb +140 -0
  34. data/lib/active_storage/attached/one.rb +16 -19
  35. data/lib/active_storage/attached.rb +7 -22
  36. data/lib/active_storage/downloader.rb +44 -0
  37. data/lib/active_storage/downloading.rb +8 -0
  38. data/lib/active_storage/engine.rb +36 -21
  39. data/lib/active_storage/errors.rb +22 -3
  40. data/lib/active_storage/gem_version.rb +4 -4
  41. data/lib/active_storage/previewer/poppler_pdf_previewer.rb +3 -3
  42. data/lib/active_storage/previewer/video_previewer.rb +2 -3
  43. data/lib/active_storage/previewer.rb +21 -11
  44. data/lib/active_storage/reflection.rb +64 -0
  45. data/lib/active_storage/service/azure_storage_service.rb +30 -14
  46. data/lib/active_storage/service/configurator.rb +3 -1
  47. data/lib/active_storage/service/disk_service.rb +20 -16
  48. data/lib/active_storage/service/gcs_service.rb +48 -46
  49. data/lib/active_storage/service/mirror_service.rb +1 -1
  50. data/lib/active_storage/service/s3_service.rb +10 -9
  51. data/lib/active_storage/service.rb +5 -6
  52. data/lib/active_storage/transformers/image_processing_transformer.rb +39 -0
  53. data/lib/active_storage/transformers/mini_magick_transformer.rb +38 -0
  54. data/lib/active_storage/transformers/transformer.rb +42 -0
  55. data/lib/active_storage.rb +13 -292
  56. data/lib/tasks/activestorage.rake +7 -0
  57. metadata +28 -16
  58. data/app/models/active_storage/filename/parameters.rb +0 -36
  59. data/lib/active_storage/attached/macros.rb +0 -110
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 792960d190b46efa9aa05e1d3d4a1f2d72e4e73fe4ce9a82da449bbc519400c1
4
- data.tar.gz: bb8596c6a65926cab7801e488d2ebbe11be080004c14f518ccdc3d885b6c87fd
3
+ metadata.gz: c76cc0190a59a7e19312ae68c2b6c3712f62eca50d9fa4d287cdc6feca94a5aa
4
+ data.tar.gz: 6d8f47c3d81c83b98b0dfc254a6e9fe6ae9b447501db6176cb96691ceb77c61c
5
5
  SHA512:
6
- metadata.gz: 82f3c2edb892e157fbd65ef6a5be34b0519ece67c98feeba239568309e6f7b4645c45baa17e0a8ceea182533f78cdae2c92fee8ffc786b9c117b63262dd8e68d
7
- data.tar.gz: 54be9ea3dfda2340771455fd2b907cce453c5cd3e47c242c14e0a50ff2baf80eeea392d02bd93247a09d5da826ee309b10b2e61827592d3e68babf578b4ae4b1
6
+ metadata.gz: a86e9a4fd481f1aa56946f24ff7e02869fe6591952929021e5c46428b230a34f18f324847db51eb0ebfd17ed8f43fb61f215798997766d072a6dbf51de21369d
7
+ data.tar.gz: 0231fa7771d92de8b9a9012291d69e2c5b976af3fa3f932c5fd0331f9cccd76ad90887d1101f96d47a6c7949832dabff1f1011412ab27a4a4ed76091ba851e10
data/CHANGELOG.md CHANGED
@@ -1,209 +1,159 @@
1
- ## Rails 5.2.8 (May 09, 2022) ##
1
+ ## Rails 6.0.0.beta1 (January 18, 2019) ##
2
2
 
3
- * No changes.
3
+ * Replace `config.active_storage.queue` with two options that indicate which
4
+ queues analysis and purge jobs should use, respectively:
4
5
 
6
+ * `config.active_storage.queues.analysis`
7
+ * `config.active_storage.queues.purge`
5
8
 
6
- ## Rails 5.2.7.1 (April 26, 2022) ##
7
-
8
- * No changes.
9
-
10
-
11
- ## Rails 5.2.7 (March 10, 2022) ##
12
-
13
- * Fix `ActiveStorage.supported_image_processing_methods` and
14
- `ActiveStorage.unsupported_image_processing_arguments` that were not being applied.
15
-
16
- *Rafael Mendonça França*
17
-
18
-
19
- ## Rails 5.2.6.3 (March 08, 2022) ##
20
-
21
- * Added image transformation validation via configurable allow-list.
22
-
23
- Variant now offers a configurable allow-list for
24
- transformation methods in addition to a configurable deny-list for arguments.
25
-
26
- [CVE-2022-21831]
27
-
28
-
29
- ## Rails 5.2.6.2 (February 11, 2022) ##
30
-
31
- * No changes.
32
-
33
-
34
- ## Rails 5.2.6.1 (February 11, 2022) ##
35
-
36
- * No changes.
37
-
38
-
39
- ## Rails 5.2.6 (May 05, 2021) ##
40
-
41
- * No changes.
42
-
43
-
44
- ## Rails 5.2.5 (March 26, 2021) ##
45
-
46
- * Marcel is upgraded to version 1.0.0 to avoid a dependency on GPL-licensed
47
- mime types data.
9
+ `config.active_storage.queue` is preferred over the new options when it's
10
+ set, but it is deprecated and will be removed in Rails 6.1.
48
11
 
49
12
  *George Claghorn*
50
13
 
51
- * The Poppler PDF previewer renders a preview image using the original
52
- document's crop box rather than its media box, hiding print margins. This
53
- matches the behavior of the MuPDF previewer.
54
-
55
- *Vincent Robert*
56
-
57
-
58
- ## Rails 5.2.4.6 (May 05, 2021) ##
59
-
60
- * No changes.
61
-
62
-
63
- ## Rails 5.2.4.5 (February 10, 2021) ##
64
-
65
- * No changes.
14
+ * Permit generating variants of TIFF images.
66
15
 
16
+ *Luciano Sousa*
67
17
 
68
- ## Rails 5.2.4.4 (September 09, 2020) ##
18
+ * Use base36 (all lowercase) for all new Blob keys to prevent
19
+ collisions and undefined behavior with case-insensitive filesystems and
20
+ database indices.
69
21
 
70
- * No changes.
22
+ *Julik Tarkhanov*
71
23
 
24
+ * It doesn’t include an `X-CSRF-Token` header if a meta tag is not found on
25
+ the page. It previously included one with a value of `undefined`.
72
26
 
73
- ## Rails 5.2.4.3 (May 18, 2020) ##
74
-
75
- * [CVE-2020-8162] Include Content-Length in signature for ActiveStorage direct upload
76
-
77
-
78
- ## Rails 5.2.4.2 (March 19, 2020) ##
79
-
80
- * No changes.
81
-
82
-
83
- ## Rails 5.2.4.1 (December 18, 2019) ##
84
-
85
- * No changes.
86
-
87
-
88
- ## Rails 5.2.4 (November 27, 2019) ##
89
-
90
- * No changes.
91
-
92
-
93
- ## Rails 5.2.3 (March 27, 2019) ##
94
-
95
- * No changes.
96
-
97
-
98
- ## Rails 5.2.2.1 (March 11, 2019) ##
99
-
100
- * No changes.
101
-
102
-
103
- ## Rails 5.2.2 (December 04, 2018) ##
104
-
105
- * Support multiple submit buttons in Active Storage forms.
106
-
107
- *Chrıs Seelus*
27
+ *Cameron Bothner*
108
28
 
109
29
  * Fix `ArgumentError` when uploading to amazon s3
110
30
 
111
31
  *Hiroki Sanpei*
112
32
 
113
- * Add a foreign-key constraint to the `active_storage_attachments` table for blobs.
114
-
115
- *George Claghorn*
116
-
117
- * Discard `ActiveStorage::PurgeJobs` for missing blobs.
118
-
119
- *George Claghorn*
33
+ * Add progressive JPG to default list of variable content types
120
34
 
121
- * Fix uploading Tempfiles to Azure Storage.
35
+ *Maurice Kühlborn*
122
36
 
123
- *George Claghorn*
37
+ * Add `ActiveStorage.routes_prefix` for configuring generated routes.
124
38
 
39
+ *Chris Bisnett*
125
40
 
126
- ## Rails 5.2.1.1 (November 27, 2018) ##
41
+ * `ActiveStorage::Service::AzureStorageService` only handles specifically
42
+ relevant types of `Azure::Core::Http::HTTPError`. It previously obscured
43
+ other types of `HTTPError`, which is the azure-storage gem’s catch-all
44
+ exception class.
127
45
 
128
- * Prevent content type and disposition bypass in storage service URLs.
46
+ *Cameron Bothner*
129
47
 
130
- Fix CVE-2018-16477.
48
+ * `ActiveStorage::DiskController#show` generates a 404 Not Found response when
49
+ the requested file is missing from the disk service. It previously raised
50
+ `Errno::ENOENT`.
131
51
 
132
- *Rosa Gutierrez*
52
+ *Cameron Bothner*
133
53
 
54
+ * `ActiveStorage::Blob#download` and `ActiveStorage::Blob#open` raise
55
+ `ActiveStorage::FileNotFoundError` when the corresponding file is missing
56
+ from the storage service. Services translate service-specific missing object
57
+ exceptions (e.g. `Google::Cloud::NotFoundError` for the GCS service and
58
+ `Errno::ENOENT` for the disk service) into
59
+ `ActiveStorage::FileNotFoundError`.
134
60
 
135
- ## Rails 5.2.1 (August 07, 2018) ##
61
+ *Cameron Bothner*
136
62
 
137
- * Fix direct upload with zero-byte files.
63
+ * Added the `ActiveStorage::SetCurrent` concern for custom Active Storage
64
+ controllers that can't inherit from `ActiveStorage::BaseController`.
138
65
 
139
66
  *George Claghorn*
140
67
 
141
- * Exclude JSON root from `active_storage/direct_uploads#create` response.
68
+ * Active Storage error classes like `ActiveStorage::IntegrityError` and
69
+ `ActiveStorage::UnrepresentableError` now inherit from `ActiveStorage::Error`
70
+ instead of `StandardError`. This permits rescuing `ActiveStorage::Error` to
71
+ handle all Active Storage errors.
142
72
 
143
- *Javan Makhmali*
73
+ *Andrei Makarov*, *George Claghorn*
144
74
 
75
+ * Uploaded files assigned to a record are persisted to storage when the record
76
+ is saved instead of immediately.
145
77
 
146
- ## Rails 5.2.0 (April 09, 2018) ##
78
+ In Rails 5.2, the following causes an uploaded file in `params[:avatar]` to
79
+ be stored:
147
80
 
148
- * Allow full use of the AWS S3 SDK options for authentication. If an
149
- explicit AWS key pair and/or region is not provided in `storage.yml`,
150
- attempt to use environment variables, shared credentials, or IAM
151
- (instance or task) role credentials. Order of precedence is determined
152
- by the [AWS SDK](https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/setup-config.html).
81
+ ```ruby
82
+ @user.avatar = params[:avatar]
83
+ ```
153
84
 
154
- *Brian Knight*
85
+ In Rails 6, the uploaded file is stored when `@user` is successfully saved.
155
86
 
156
- * Remove path config option from Azure service.
87
+ *George Claghorn*
157
88
 
158
- The Active Storage service for Azure Storage has an option called `path`
159
- that is ambiguous in meaning. It needs to be set to the primary blob
160
- storage endpoint but that can be determined from the blobs client anyway.
89
+ * Add the ability to reflect on defined attachments using the existing
90
+ ActiveRecord reflection mechanism.
161
91
 
162
- To simplify the configuration, we've removed the `path` option and
163
- now get the endpoint from the blobs client instead.
92
+ *Kevin Deisz*
164
93
 
165
- Closes #32225.
94
+ * Variant arguments of `false` or `nil` will no longer be passed to the
95
+ processor. For example, the following will not have the monochrome
96
+ variation applied:
166
97
 
167
- *Andrew White*
98
+ ```ruby
99
+ avatar.variant(monochrome: false)
100
+ ```
168
101
 
169
- * Generate root-relative paths in disk service URL methods.
102
+ *Jacob Smith*
170
103
 
171
- Obviate the disk service's `:host` configuration option.
104
+ * Generated attachment getter and setter methods are created
105
+ within the model's `GeneratedAssociationMethods` module to
106
+ allow overriding and composition using `super`.
172
107
 
173
- *George Claghorn*
108
+ *Josh Susser*, *Jamon Douglas*
109
+
110
+ * Add `ActiveStorage::Blob#open`, which downloads a blob to a tempfile on disk
111
+ and yields the tempfile. Deprecate `ActiveStorage::Downloading`.
174
112
 
175
- * Add source code to published npm package.
113
+ *David Robertson*, *George Claghorn*
176
114
 
177
- This allows activestorage users to depend on the javascript source code
178
- rather than the compiled code, which can produce smaller javascript bundles.
115
+ * Pass in `identify: false` as an argument when providing a `content_type` for
116
+ `ActiveStorage::Attached::{One,Many}#attach` to bypass automatic content
117
+ type inference. For example:
179
118
 
180
- *Richard Macklin*
119
+ ```ruby
120
+ @message.image.attach(
121
+ io: File.open('/path/to/file'),
122
+ filename: 'file.pdf',
123
+ content_type: 'application/pdf',
124
+ identify: false
125
+ )
126
+ ```
181
127
 
182
- * Preserve display aspect ratio when extracting width and height from videos
183
- with rectangular samples in `ActiveStorage::Analyzer::VideoAnalyzer`.
128
+ *Ryan Davidson*
184
129
 
185
- When a video contains a display aspect ratio, emit it in metadata as
186
- `:display_aspect_ratio` rather than the ambiguous `:aspect_ratio`. Compute
187
- its height by scaling its encoded frame width according to the DAR.
130
+ * The Google Cloud Storage service properly supports streaming downloads.
131
+ It now requires version 1.11 or newer of the google-cloud-storage gem.
188
132
 
189
133
  *George Claghorn*
190
134
 
191
- * Use `after_destroy_commit` instead of `before_destroy` for purging
192
- attachments when a record is destroyed.
135
+ * Use the [ImageProcessing](https://github.com/janko-m/image_processing) gem
136
+ for Active Storage variants, and deprecate the MiniMagick backend.
193
137
 
194
- *Hiroki Zenigami*
138
+ This means that variants are now automatically oriented if the original
139
+ image was rotated. Also, in addition to the existing ImageMagick
140
+ operations, variants can now use `:resize_to_fit`, `:resize_to_fill`, and
141
+ other ImageProcessing macros. These are now recommended over raw `:resize`,
142
+ as they also sharpen the thumbnail after resizing.
195
143
 
196
- * Force `:attachment` disposition for specific, configurable content types.
197
- This mitigates possible security issues such as XSS or phishing when
198
- serving them inline. A list of such content types is included by default,
199
- and can be configured via `content_types_to_serve_as_binary`.
144
+ The ImageProcessing gem also comes with a backend implemented on
145
+ [libvips](http://jcupitt.github.io/libvips/), an alternative to
146
+ ImageMagick which has significantly better performance than
147
+ ImageMagick in most cases, both in terms of speed and memory usage. In
148
+ Active Storage it's now possible to switch to the libvips backend by
149
+ changing `Rails.application.config.active_storage.variant_processor` to
150
+ `:vips`.
200
151
 
201
- *Rosa Gutierrez*
152
+ *Janko Marohnić*
202
153
 
203
- * Fix the gem adding the migrations files to the package.
154
+ * Rails 6 requires Ruby 2.5.0 or newer.
204
155
 
205
- *Yuji Yaginuma*
156
+ *Jeremy Daer*, *Kasper Timm Hansen*
206
157
 
207
- * Added to Rails.
208
158
 
209
- *DHH*
159
+ Please check [5-2-stable](https://github.com/rails/rails/blob/5-2-stable/activestorage/CHANGELOG.md) for previous changes.
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2017-2018 David Heinemeier Hansson, Basecamp
1
+ Copyright (c) 2017-2019 David Heinemeier Hansson, Basecamp
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -4,11 +4,11 @@ Active Storage makes it simple to upload and reference files in cloud services l
4
4
 
5
5
  Files can be uploaded from the server to the cloud or directly from the client to the cloud.
6
6
 
7
- Image files can furthermore be transformed using on-demand variants for quality, aspect ratio, size, or any other [MiniMagick](https://github.com/minimagick/minimagick) supported transformation.
7
+ Image files can furthermore be transformed using on-demand variants for quality, aspect ratio, size, or any other [MiniMagick](https://github.com/minimagick/minimagick) or [Vips](http://www.rubydoc.info/gems/ruby-vips/Vips/Image) supported transformation.
8
8
 
9
9
  ## Compared to other storage solutions
10
10
 
11
- A key difference to how Active Storage works compared to other attachment solutions in Rails is through the use of built-in [Blob](https://github.com/rails/rails/blob/5-2-stable/activestorage/app/models/active_storage/blob.rb) and [Attachment](https://github.com/rails/rails/blob/5-2-stable/activestorage/app/models/active_storage/attachment.rb) models (backed by Active Record). This means existing application models do not need to be modified with additional columns to associate with files. Active Storage uses polymorphic associations via the `Attachment` join model, which then connects to the actual `Blob`.
11
+ A key difference to how Active Storage works compared to other attachment solutions in Rails is through the use of built-in [Blob](https://github.com/rails/rails/blob/master/activestorage/app/models/active_storage/blob.rb) and [Attachment](https://github.com/rails/rails/blob/master/activestorage/app/models/active_storage/attachment.rb) models (backed by Active Record). This means existing application models do not need to be modified with additional columns to associate with files. Active Storage uses polymorphic associations via the `Attachment` join model, which then connects to the actual `Blob`.
12
12
 
13
13
  `Blob` models store attachment metadata (filename, content-type, etc.), and their identifier key in the storage service. Blob models do not store the actual binary data. They are intended to be immutable in spirit. One file, one blob. You can associate the same blob with multiple application models as well. And if you want to do transformations of a given `Blob`, the idea is that you'll simply create a new one, rather than attempt to mutate the existing one (though of course you can delete the previous version later if you don't need it).
14
14
 
@@ -16,6 +16,8 @@ A key difference to how Active Storage works compared to other attachment soluti
16
16
 
17
17
  Run `rails active_storage:install` to copy over active_storage migrations.
18
18
 
19
+ NOTE: If the task cannot be found, verify that `require "active_storage/engine"` is present in `config/application.rb`.
20
+
19
21
  ## Examples
20
22
 
21
23
  One attachment:
@@ -99,7 +101,7 @@ Variation of image attachment:
99
101
 
100
102
  ```erb
101
103
  <%# Hitting the variant URL will lazy transform the original blob and then redirect to its new service location %>
102
- <%= image_tag user.avatar.variant(resize: "100x100") %>
104
+ <%= image_tag user.avatar.variant(resize_to_fit: [100, 100]) %>
103
105
  ```
104
106
 
105
107
  ## Direct uploads
@@ -116,8 +118,7 @@ Active Storage, with its included JavaScript library, supports uploading directl
116
118
  ```
117
119
  Using the npm package:
118
120
  ```js
119
- import * as ActiveStorage from "activestorage"
120
- ActiveStorage.start()
121
+ require("@rails/activestorage").start()
121
122
  ```
122
123
  2. Annotate file inputs with the direct upload URL.
123
124
 
@@ -560,7 +560,10 @@
560
560
  this.xhr.setRequestHeader("Content-Type", "application/json");
561
561
  this.xhr.setRequestHeader("Accept", "application/json");
562
562
  this.xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
563
- this.xhr.setRequestHeader("X-CSRF-Token", getMetaValue("csrf-token"));
563
+ var csrfToken = getMetaValue("csrf-token");
564
+ if (csrfToken != undefined) {
565
+ this.xhr.setRequestHeader("X-CSRF-Token", csrfToken);
566
+ }
564
567
  this.xhr.addEventListener("load", function(event) {
565
568
  return _this.requestDidLoad(event);
566
569
  });
@@ -1,10 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # The base controller for all ActiveStorage controllers.
3
+ # The base class for all Active Storage controllers.
4
4
  class ActiveStorage::BaseController < ActionController::Base
5
- protect_from_forgery with: :exception
5
+ include ActiveStorage::SetCurrent
6
6
 
7
- before_action do
8
- ActiveStorage::Current.host = request.base_url
9
- end
7
+ protect_from_forgery with: :exception
10
8
  end
@@ -8,7 +8,7 @@ class ActiveStorage::BlobsController < ActiveStorage::BaseController
8
8
  include ActiveStorage::SetBlob
9
9
 
10
10
  def show
11
- expires_in ActiveStorage::Blob.service.url_expires_in
11
+ expires_in ActiveStorage.service_urls_expire_in
12
12
  redirect_to @blob.service_url(disposition: params[:disposition])
13
13
  end
14
14
  end
@@ -13,16 +13,19 @@ class ActiveStorage::DiskController < ActiveStorage::BaseController
13
13
  else
14
14
  head :not_found
15
15
  end
16
+ rescue Errno::ENOENT
17
+ head :not_found
16
18
  end
17
19
 
18
20
  def update
19
21
  if token = decode_verified_token
20
22
  if acceptable_content?(token)
21
23
  disk_service.upload token[:key], request.body, checksum: token[:checksum]
22
- head :no_content
23
24
  else
24
25
  head :unprocessable_entity
25
26
  end
27
+ else
28
+ head :not_found
26
29
  end
27
30
  rescue ActiveStorage::IntegrityError
28
31
  head :unprocessable_entity
@@ -8,7 +8,7 @@ class ActiveStorage::RepresentationsController < ActiveStorage::BaseController
8
8
  include ActiveStorage::SetBlob
9
9
 
10
10
  def show
11
- expires_in ActiveStorage::Blob.service.url_expires_in
11
+ expires_in ActiveStorage.service_urls_expire_in
12
12
  redirect_to @blob.representation(params[:variation_key]).processed.service_url(disposition: params[:disposition])
13
13
  end
14
14
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Sets the <tt>ActiveStorage::Current.host</tt> attribute, which the disk service uses to generate URLs.
4
+ # Include this concern in custom controllers that call ActiveStorage::Blob#service_url,
5
+ # ActiveStorage::Variant#service_url, or ActiveStorage::Preview#service_url so the disk service can
6
+ # generate URLs using the same host, protocol, and base path as the current request.
7
+ module ActiveStorage::SetCurrent
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ before_action do
12
+ ActiveStorage::Current.host = request.base_url
13
+ end
14
+ end
15
+ end
@@ -17,7 +17,12 @@ export class BlobRecord {
17
17
  this.xhr.setRequestHeader("Content-Type", "application/json")
18
18
  this.xhr.setRequestHeader("Accept", "application/json")
19
19
  this.xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest")
20
- this.xhr.setRequestHeader("X-CSRF-Token", getMetaValue("csrf-token"))
20
+
21
+ const csrfToken = getMetaValue("csrf-token")
22
+ if (csrfToken != undefined) {
23
+ this.xhr.setRequestHeader("X-CSRF-Token", csrfToken)
24
+ }
25
+
21
26
  this.xhr.addEventListener("load", event => this.requestDidLoad(event))
22
27
  this.xhr.addEventListener("error", event => this.requestDidError(event))
23
28
  }
@@ -2,6 +2,10 @@
2
2
 
3
3
  # Provides asynchronous analysis of ActiveStorage::Blob records via ActiveStorage::Blob#analyze_later.
4
4
  class ActiveStorage::AnalyzeJob < ActiveStorage::BaseJob
5
+ queue_as { ActiveStorage.queues[:analysis] }
6
+
7
+ retry_on ActiveStorage::IntegrityError, attempts: 10, wait: :exponentially_longer
8
+
5
9
  def perform(blob)
6
10
  blob.analyze
7
11
  end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class ActiveStorage::BaseJob < ActiveJob::Base
4
- queue_as { ActiveStorage.queue }
5
4
  end
@@ -2,7 +2,10 @@
2
2
 
3
3
  # Provides asynchronous purging of ActiveStorage::Blob records via ActiveStorage::Blob#purge_later.
4
4
  class ActiveStorage::PurgeJob < ActiveStorage::BaseJob
5
+ queue_as { ActiveStorage.queues[:purge] }
6
+
5
7
  discard_on ActiveRecord::RecordNotFound
8
+ retry_on ActiveRecord::Deadlocked, attempts: 10, wait: :exponentially_longer
6
9
 
7
10
  def perform(blob)
8
11
  blob.purge
@@ -3,9 +3,8 @@
3
3
  require "active_support/core_ext/module/delegation"
4
4
 
5
5
  # Attachments associate records with blobs. Usually that's a one record-many blobs relationship,
6
- # but it is possible to associate many different records with the same blob. If you're doing that,
7
- # you'll want to declare with <tt>has_one/many_attached :thingy, dependent: false</tt>, so that destroying
8
- # any one record won't destroy the blob as well. (Then you'll need to do your own garbage collecting, though).
6
+ # but it is possible to associate many different records with the same blob. A foreign-key constraint
7
+ # on the attachments table prevents blobs from being purged if they’re still attached to any records.
9
8
  class ActiveStorage::Attachment < ActiveRecord::Base
10
9
  self.table_name = "active_storage_attachments"
11
10
 
@@ -15,17 +14,18 @@ class ActiveStorage::Attachment < ActiveRecord::Base
15
14
  delegate_missing_to :blob
16
15
 
17
16
  after_create_commit :analyze_blob_later, :identify_blob
17
+ after_destroy_commit :purge_dependent_blob_later
18
18
 
19
- # Synchronously purges the blob (deletes it from the configured service) and destroys the attachment.
19
+ # Synchronously deletes the attachment and {purges the blob}[rdoc-ref:ActiveStorage::Blob#purge].
20
20
  def purge
21
- destroy
22
- blob.purge
21
+ delete
22
+ blob&.purge
23
23
  end
24
24
 
25
- # Destroys the attachment and asynchronously purges the blob (deletes it from the configured service).
25
+ # Deletes the attachment and {enqueues a background job}[rdoc-ref:ActiveStorage::Blob#purge_later] to purge the blob.
26
26
  def purge_later
27
- destroy
28
- blob.purge_later
27
+ delete
28
+ blob&.purge_later
29
29
  end
30
30
 
31
31
  private
@@ -36,4 +36,13 @@ class ActiveStorage::Attachment < ActiveRecord::Base
36
36
  def analyze_blob_later
37
37
  blob.analyze_later unless blob.analyzed?
38
38
  end
39
+
40
+ def purge_dependent_blob_later
41
+ blob&.purge_later if dependent == :purge_later
42
+ end
43
+
44
+
45
+ def dependent
46
+ record.attachment_reflections[name]&.options[:dependent]
47
+ end
39
48
  end
@@ -10,7 +10,7 @@ module ActiveStorage::Blob::Representable
10
10
  # Returns an ActiveStorage::Variant instance with the set of +transformations+ provided. This is only relevant for image
11
11
  # files, and it allows any image to be transformed for size, colors, and the like. Example:
12
12
  #
13
- # avatar.variant(resize: "100x100").processed.service_url
13
+ # avatar.variant(resize_to_fit: [100, 100]).processed.service_url
14
14
  #
15
15
  # This will create and process a variant of the avatar blob that's constrained to a height and width of 100px.
16
16
  # Then it'll upload said variant to the service according to a derivative key of the blob and the transformations.
@@ -18,7 +18,7 @@ module ActiveStorage::Blob::Representable
18
18
  # Frequently, though, you don't actually want to transform the variant right away. But rather simply refer to a
19
19
  # specific variant that can be created by a controller on-demand. Like so:
20
20
  #
21
- # <%= image_tag Current.user.avatar.variant(resize: "100x100") %>
21
+ # <%= image_tag Current.user.avatar.variant(resize_to_fit: [100, 100]) %>
22
22
  #
23
23
  # This will create a URL for that specific blob with that specific variant, which the ActiveStorage::RepresentationsController
24
24
  # can then produce on-demand.
@@ -43,13 +43,13 @@ module ActiveStorage::Blob::Representable
43
43
  # from a non-image blob. Active Storage comes with built-in previewers for videos and PDF documents. The video previewer
44
44
  # extracts the first frame from a video and the PDF previewer extracts the first page from a PDF document.
45
45
  #
46
- # blob.preview(resize: "100x100").processed.service_url
46
+ # blob.preview(resize_to_fit: [100, 100]).processed.service_url
47
47
  #
48
48
  # Avoid processing previews synchronously in views. Instead, link to a controller action that processes them on demand.
49
49
  # Active Storage provides one, but you may want to create your own (for example, if you need authentication). Here’s
50
50
  # how to use the built-in version:
51
51
  #
52
- # <%= image_tag video.preview(resize: "100x100") %>
52
+ # <%= image_tag video.preview(resize_to_fit: [100, 100]) %>
53
53
  #
54
54
  # This method raises ActiveStorage::UnpreviewableError if no previewer accepts the receiving blob. To determine
55
55
  # whether a blob is accepted by any previewer, call ActiveStorage::Blob#previewable?.
@@ -69,7 +69,7 @@ module ActiveStorage::Blob::Representable
69
69
 
70
70
  # Returns an ActiveStorage::Preview for a previewable blob or an ActiveStorage::Variant for a variable image blob.
71
71
  #
72
- # blob.representation(resize: "100x100").processed.service_url
72
+ # blob.representation(resize_to_fit: [100, 100]).processed.service_url
73
73
  #
74
74
  # Raises ActiveStorage::UnrepresentableError if the receiving blob is neither variable nor previewable. Call
75
75
  # ActiveStorage::Blob#representable? to determine whether a blob is representable.