aboutsummaryrefslogtreecommitdiffstats
path: root/activestorage
diff options
context:
space:
mode:
Diffstat (limited to 'activestorage')
-rw-r--r--activestorage/README.md8
-rw-r--r--activestorage/app/controllers/active_storage/blobs_controller.rb1
-rw-r--r--activestorage/app/controllers/active_storage/variants_controller.rb1
-rw-r--r--activestorage/app/jobs/active_storage/purge_job.rb2
-rw-r--r--activestorage/app/models/active_storage/attachment.rb2
-rw-r--r--activestorage/app/models/active_storage/blob.rb36
-rw-r--r--activestorage/app/models/active_storage/variant.rb14
-rw-r--r--activestorage/app/models/active_storage/variation.rb8
-rw-r--r--activestorage/db/migrate/20170806125915_create_active_storage_tables.rb20
-rw-r--r--activestorage/lib/active_storage/attached.rb2
-rw-r--r--activestorage/lib/active_storage/attached/macros.rb44
-rw-r--r--activestorage/lib/active_storage/attached/many.rb2
-rw-r--r--activestorage/lib/active_storage/engine.rb2
-rw-r--r--activestorage/lib/active_storage/service.rb24
-rw-r--r--activestorage/lib/active_storage/service/azure_storage_service.rb2
-rw-r--r--activestorage/lib/active_storage/service/disk_service.rb2
-rw-r--r--activestorage/lib/active_storage/service/gcs_service.rb2
-rw-r--r--activestorage/lib/active_storage/service/mirror_service.rb12
-rw-r--r--activestorage/lib/active_storage/service/s3_service.rb2
-rw-r--r--activestorage/lib/tasks/activestorage.rake2
-rw-r--r--activestorage/test/controllers/blobs_controller_test.rb15
-rw-r--r--activestorage/test/models/attachments_test.rb7
-rw-r--r--activestorage/test/service/configurations.yml14
-rw-r--r--activestorage/test/template/image_tag_test.rb4
-rw-r--r--activestorage/test/test_helper.rb15
25 files changed, 123 insertions, 120 deletions
diff --git a/activestorage/README.md b/activestorage/README.md
index 957adc05c3..d4ffe0c484 100644
--- a/activestorage/README.md
+++ b/activestorage/README.md
@@ -83,14 +83,6 @@ Variation of image attachment:
<%= image_tag user.avatar.variant(resize: "100x100") %>
```
-## Installation
-
-1. Run `rails activestorage:install` to create needed directories, migrations, and configuration.
-2. Optional: Add `gem "aws-sdk", "~> 2"` to your Gemfile if you want to use AWS S3.
-3. Optional: Add `gem "google-cloud-storage", "~> 1.3"` to your Gemfile if you want to use Google Cloud Storage.
-4. Optional: Add `gem "azure-storage"` to your Gemfile if you want to use Microsoft Azure.
-5. Optional: Add `gem "mini_magick"` to your Gemfile if you want to use variants.
-
## Direct uploads
Active Storage, with its included JavaScript library, supports uploading directly from the client to the cloud.
diff --git a/activestorage/app/controllers/active_storage/blobs_controller.rb b/activestorage/app/controllers/active_storage/blobs_controller.rb
index 05af29f8b2..cff88bd488 100644
--- a/activestorage/app/controllers/active_storage/blobs_controller.rb
+++ b/activestorage/app/controllers/active_storage/blobs_controller.rb
@@ -5,6 +5,7 @@
class ActiveStorage::BlobsController < ActionController::Base
def show
if blob = find_signed_blob
+ expires_in 5.minutes # service_url defaults to 5 minutes
redirect_to blob.service_url(disposition: disposition_param)
else
head :not_found
diff --git a/activestorage/app/controllers/active_storage/variants_controller.rb b/activestorage/app/controllers/active_storage/variants_controller.rb
index 994c57aafd..b72b0ff7f5 100644
--- a/activestorage/app/controllers/active_storage/variants_controller.rb
+++ b/activestorage/app/controllers/active_storage/variants_controller.rb
@@ -5,6 +5,7 @@
class ActiveStorage::VariantsController < ActionController::Base
def show
if blob = find_signed_blob
+ expires_in 5.minutes # service_url defaults to 5 minutes
redirect_to ActiveStorage::Variant.new(blob, decoded_variation).processed.service_url(disposition: disposition_param)
else
head :not_found
diff --git a/activestorage/app/jobs/active_storage/purge_job.rb b/activestorage/app/jobs/active_storage/purge_job.rb
index 815f908e6c..b504ee0df4 100644
--- a/activestorage/app/jobs/active_storage/purge_job.rb
+++ b/activestorage/app/jobs/active_storage/purge_job.rb
@@ -1,4 +1,4 @@
-# Provides delayed purging of attachments or blobs using their `#purge_later` method.
+# Provides delayed purging of attachments or blobs using their +#purge_later+ method.
class ActiveStorage::PurgeJob < ActiveJob::Base
# FIXME: Limit this to a custom ActiveStorage error
retry_on StandardError
diff --git a/activestorage/app/models/active_storage/attachment.rb b/activestorage/app/models/active_storage/attachment.rb
index e94fc69bba..07b5733ff8 100644
--- a/activestorage/app/models/active_storage/attachment.rb
+++ b/activestorage/app/models/active_storage/attachment.rb
@@ -21,7 +21,7 @@ class ActiveStorage::Attachment < ActiveRecord::Base
# Purging an attachment means purging the blob, which means talking to the service, which means
# talking over the internet. Whenever you're doing that, it's a good idea to put that work in a job,
- # so it doesn't hold up other operations. That's what #purge_later provides.
+ # so it doesn't hold up other operations. That's what +#purge_later+ provides.
def purge_later
ActiveStorage::PurgeJob.perform_later(self)
end
diff --git a/activestorage/app/models/active_storage/blob.rb b/activestorage/app/models/active_storage/blob.rb
index c72073f9f6..113a7f774d 100644
--- a/activestorage/app/models/active_storage/blob.rb
+++ b/activestorage/app/models/active_storage/blob.rb
@@ -29,7 +29,7 @@ class ActiveStorage::Blob < ActiveRecord::Base
find ActiveStorage.verifier.verify(id, purpose: :blob_id)
end
- # Returns a new, unsaved blob instance after the `io` has been uploaded to the service.
+ # Returns a new, unsaved blob instance after the +io+ has been uploaded to the service.
def build_after_upload(io:, filename:, content_type: nil, metadata: nil)
new.tap do |blob|
blob.filename = filename
@@ -40,8 +40,8 @@ class ActiveStorage::Blob < ActiveRecord::Base
end
end
- # Returns a saved blob instance after the `io` has been uploaded to the service. Note, the blob is first built,
- # then the `io` is uploaded, then the blob is saved. This is doing to avoid opening a transaction and talking to
+ # Returns a saved blob instance after the +io+ has been uploaded to the service. Note, the blob is first built,
+ # then the +io+ is uploaded, then the blob is saved. This is doing to avoid opening a transaction and talking to
# the service during that (which is a bad idea and leads to deadlocks).
def create_after_upload!(io:, filename:, content_type: nil, metadata: nil)
build_after_upload(io: io, filename: filename, content_type: content_type, metadata: metadata).tap(&:save!)
@@ -72,7 +72,7 @@ class ActiveStorage::Blob < ActiveRecord::Base
self[:key] ||= self.class.generate_unique_secure_token
end
- # Returns a `ActiveStorage::Filename` instance of the filename that can be queried for basename, extension, and
+ # Returns a ActiveStorage::Filename instance of the filename that can be queried for basename, extension, and
# a sanitized version of the filename that's safe to use in URLs.
def filename
ActiveStorage::Filename.new(self[:filename])
@@ -98,7 +98,7 @@ class ActiveStorage::Blob < ActiveRecord::Base
content_type.start_with?("text")
end
- # Returns a `ActiveStorage::Variant` instance with the set of `transformations` passed in. This is only relevant
+ # Returns a ActiveStorage::Variant instance with the set of +transformations+ passed in. This is only relevant
# for image files, and it allows any image to be transformed for size, colors, and the like. Example:
#
# avatar.variant(resize: "100x100").processed.service_url
@@ -111,7 +111,7 @@ class ActiveStorage::Blob < ActiveRecord::Base
#
# <%= image_tag url_for(Current.user.avatar.variant(resize: "100x100")) %>
#
- # This will create a URL for that specific blob with that specific variant, which the `ActiveStorage::VariantsController`
+ # This will create a URL for that specific blob with that specific variant, which the ActiveStorage::VariantsController
# can then produce on-demand.
def variant(transformations)
ActiveStorage::Variant.new(self, ActiveStorage::Variation.new(transformations))
@@ -119,9 +119,9 @@ class ActiveStorage::Blob < ActiveRecord::Base
# Returns the URL of the blob on the service. This URL is intended to be short-lived for security and not used directly
- # with users. Instead, the `service_url` should only be exposed as a redirect from a stable, possibly authenticated URL.
- # Hiding the `service_url` behind a redirect also gives you the power to change services without updating all URLs. And
- # it allows permanent URLs that redirect to the `service_url` to be cached in the view.
+ # with users. Instead, the +service_url+ should only be exposed as a redirect from a stable, possibly authenticated URL.
+ # Hiding the +service_url+ behind a redirect also gives you the power to change services without updating all URLs. And
+ # it allows permanent URLs that redirect to the +service_url+ to be cached in the view.
def service_url(expires_in: 5.minutes, disposition: :inline)
service.url key, expires_in: expires_in, disposition: disposition, filename: filename, content_type: content_type
end
@@ -132,21 +132,21 @@ class ActiveStorage::Blob < ActiveRecord::Base
service.url_for_direct_upload key, expires_in: expires_in, content_type: content_type, content_length: byte_size, checksum: checksum
end
- # Returns a Hash of headers for `service_url_for_direct_upload` requests.
+ # Returns a Hash of headers for +service_url_for_direct_upload+ requests.
def service_headers_for_direct_upload
service.headers_for_direct_upload key, filename: filename, content_type: content_type, content_length: byte_size, checksum: checksum
end
- # Uploads the `io` to the service on the `key` for this blob. Blobs are intended to be immutable, so you shouldn't be
+ # Uploads the +io+ to the service on the +key+ for this blob. Blobs are intended to be immutable, so you shouldn't be
# using this method after a file has already been uploaded to fit with a blob. If you want to create a derivative blob,
# you should instead simply create a new blob based on the old one.
#
# Prior to uploading, we compute the checksum, which is sent to the service for transit integrity validation. If the
- # checksum does not match what the service receives, an exception will be raised. We also measure the size of the `io`
- # and store that in `byte_size` on the blob record.
+ # checksum does not match what the service receives, an exception will be raised. We also measure the size of the +io+
+ # and store that in +byte_size+ on the blob record.
#
- # Normally, you do not have to call this method directly at all. Use the factory class methods of `build_after_upload`
- # and `create_after_upload!`.
+ # Normally, you do not have to call this method directly at all. Use the factory class methods of +build_after_upload+
+ # and +create_after_upload!+.
def upload(io)
self.checksum = compute_checksum_in_chunks(io)
self.byte_size = io.size
@@ -162,7 +162,7 @@ class ActiveStorage::Blob < ActiveRecord::Base
# Deletes the file on the service that's associated with this blob. This should only be done if the blob is going to be
- # deleted as well or you will essentially have a dead reference. It's recommended to use the `#purge` and `#purge_later`
+ # deleted as well or you will essentially have a dead reference. It's recommended to use the +#purge+ and +#purge_later+
# methods in most circumstances.
def delete
service.delete key
@@ -170,13 +170,13 @@ class ActiveStorage::Blob < ActiveRecord::Base
# Deletes the file on the service and then destroys the blob record. This is the recommended way to dispose of unwanted
# blobs. Note, though, that deleting the file off the service will initiate a HTTP connection to the service, which may
- # be slow or prevented, so you should not use this method inside a transaction or in callbacks. Use `#purge_later` instead.
+ # be slow or prevented, so you should not use this method inside a transaction or in callbacks. Use +#purge_later+ instead.
def purge
delete
destroy
end
- # Enqueues a `ActiveStorage::PurgeJob` job that'll call `#purge`. This is the recommended way to purge blobs when the call
+ # Enqueues a ActiveStorage::PurgeJob job that'll call +#purge+. This is the recommended way to purge blobs when the call
# needs to be made from a transaction, a callback, or any other real-time scenario.
def purge_later
ActiveStorage::PurgeJob.perform_later(self)
diff --git a/activestorage/app/models/active_storage/variant.rb b/activestorage/app/models/active_storage/variant.rb
index e3f22bcb25..b9b93b4c1b 100644
--- a/activestorage/app/models/active_storage/variant.rb
+++ b/activestorage/app/models/active_storage/variant.rb
@@ -9,17 +9,17 @@
# into memory. The larger the image, the more memory is used. Because of this process, you also want to be
# considerate about when the variant is actually processed. You shouldn't be processing variants inline in a
# template, for example. Delay the processing to an on-demand controller, like the one provided in
-# `ActiveStorage::VariantsController`.
+# ActiveStorage::VariantsController.
#
# To refer to such a delayed on-demand variant, simply link to the variant through the resolved route provided
# by Active Storage like so:
#
# <%= image_tag url_for(Current.user.avatar.variant(resize: "100x100")) %>
#
-# This will create a URL for that specific blob with that specific variant, which the `ActiveStorage::VariantsController`
+# This will create a URL for that specific blob with that specific variant, which the ActiveStorage::VariantsController
# can then produce on-demand.
#
-# When you do want to actually produce the variant needed, call `#processed`. This will check that the variant
+# When you do want to actually produce the variant needed, call +#processed+. This will check that the variant
# has already been processed and uploaded to the service, and, if so, just return that. Otherwise it will perform
# the transformations, upload the variant to the service, and return itself again. Example:
#
@@ -52,12 +52,12 @@ class ActiveStorage::Variant
end
# Returns the URL of the variant on the service. This URL is intended to be short-lived for security and not used directly
- # with users. Instead, the `service_url` should only be exposed as a redirect from a stable, possibly authenticated URL.
- # Hiding the `service_url` behind a redirect also gives you the power to change services without updating all URLs. And
- # it allows permanent URLs that redirec to the `service_url` to be cached in the view.
+ # with users. Instead, the +service_url+ should only be exposed as a redirect from a stable, possibly authenticated URL.
+ # Hiding the +service_url+ behind a redirect also gives you the power to change services without updating all URLs. And
+ # it allows permanent URLs that redirect to the +service_url+ to be cached in the view.
#
# Use `url_for(variant)` (or the implied form, like `link_to variant` or `redirect_to variant`) to get the stable URL
- # for a variant that points to the `ActiveStorage::VariantsController`, which in turn will use this `#service_call` method
+ # for a variant that points to the ActiveStorage::VariantsController, which in turn will use this +#service_call+ method
# for its redirection.
def service_url(expires_in: 5.minutes, disposition: :inline)
service.url key, expires_in: expires_in, disposition: disposition, filename: blob.filename, content_type: blob.content_type
diff --git a/activestorage/app/models/active_storage/variation.rb b/activestorage/app/models/active_storage/variation.rb
index e784506b4c..24168c064c 100644
--- a/activestorage/app/models/active_storage/variation.rb
+++ b/activestorage/app/models/active_storage/variation.rb
@@ -13,12 +13,12 @@ class ActiveStorage::Variation
attr_reader :transformations
class << self
- # Returns a variation instance with the transformations that were encoded by `#encode`.
+ # Returns a variation instance with the transformations that were encoded by +#encode+.
def decode(key)
new ActiveStorage.verifier.verify(key, purpose: :variation)
end
- # Returns a signed key for the `transformations`, which can be used to refer to a specific
+ # Returns a signed key for the +transformations+, which can be used to refer to a specific
# variation in a URL or combined key (like `ActiveStorage::Variant#key`).
def encode(transformations)
ActiveStorage.verifier.generate(transformations, purpose: :variation)
@@ -30,7 +30,7 @@ class ActiveStorage::Variation
end
# Accepts an open MiniMagick image instance, like what's return by `MiniMagick::Image.read(io)`,
- # and performs the `transformations` against it. The transformed image instance is then returned.
+ # and performs the +transformations+ against it. The transformed image instance is then returned.
def transform(image)
transformations.each do |(method, argument)|
if eligible_argument?(argument)
@@ -41,7 +41,7 @@ class ActiveStorage::Variation
end
end
- # Returns a signed key for all the `transformations` that this variation was instantiated with.
+ # Returns a signed key for all the +transformations+ that this variation was instantiated with.
def key
self.class.encode(transformations)
end
diff --git a/activestorage/db/migrate/20170806125915_create_active_storage_tables.rb b/activestorage/db/migrate/20170806125915_create_active_storage_tables.rb
index 6eab7e0fa0..2c7e3c5bc6 100644
--- a/activestorage/db/migrate/20170806125915_create_active_storage_tables.rb
+++ b/activestorage/db/migrate/20170806125915_create_active_storage_tables.rb
@@ -1,24 +1,24 @@
class CreateActiveStorageTables < ActiveRecord::Migration[5.1]
def change
create_table :active_storage_blobs do |t|
- t.string :key
- t.string :filename
+ t.string :key, null: false
+ t.string :filename, null: false
t.string :content_type
t.text :metadata
- t.integer :byte_size
- t.string :checksum
- t.datetime :created_at
+ t.integer :byte_size, null: false
+ t.string :checksum, null: false
+ t.datetime :created_at, null: false
t.index [ :key ], unique: true
end
create_table :active_storage_attachments do |t|
- t.string :name
- t.string :record_type
- t.integer :record_id
- t.integer :blob_id
+ t.string :name, null: false
+ t.string :record_type, null: false
+ t.integer :record_id, null: false
+ t.integer :blob_id, null: false
- t.datetime :created_at
+ t.datetime :created_at, null: false
t.index :blob_id
t.index [ :record_type, :record_id, :name, :blob_id ], name: "index_active_storage_attachments_uniqueness", unique: true
diff --git a/activestorage/lib/active_storage/attached.rb b/activestorage/lib/active_storage/attached.rb
index 5ac8ba5377..07e0d5c3ea 100644
--- a/activestorage/lib/active_storage/attached.rb
+++ b/activestorage/lib/active_storage/attached.rb
@@ -3,7 +3,7 @@ require "action_dispatch/http/upload"
require "active_support/core_ext/module/delegation"
module ActiveStorage
-# Abstract baseclass for the concrete `ActiveStorage::Attached::One` and `ActiveStorage::Attached::Many`
+# Abstract baseclass for the concrete ActiveStorage::Attached::One and ActiveStorage::Attached::Many
# classes that both provide proxy access to the blob association for a record.
class Attached
attr_reader :name, :record
diff --git a/activestorage/lib/active_storage/attached/macros.rb b/activestorage/lib/active_storage/attached/macros.rb
index ef00033aeb..eb877f10c0 100644
--- a/activestorage/lib/active_storage/attached/macros.rb
+++ b/activestorage/lib/active_storage/attached/macros.rb
@@ -10,25 +10,23 @@ module ActiveStorage
# There is no column defined on the model side, Active Storage takes
# care of the mapping between your records and the attachment.
#
- # Under the covers, this relationship is implemented as a `has_one` association to a
- # `ActiveStorage::Attachment` record and a `has_one-through` association to a
- # `ActiveStorage::Blob` record. These associations are available as `avatar_attachment`
- # and `avatar_blob`. But you shouldn't need to work with these associations directly in
+ # Under the covers, this relationship is implemented as a +has_one+ association to a
+ # ActiveStorage::Attachment record and a +has_one-through+ association to a
+ # ActiveStorage::Blob record. These associations are available as +avatar_attachment+
+ # and +avatar_blob+. But you shouldn't need to work with these associations directly in
# most circumstances.
#
- # The system has been designed to having you go through the `ActiveStorage::Attached::One`
- # proxy that provides the dynamic proxy to the associations and factory methods, like `#attach`.
+ # The system has been designed to having you go through the ActiveStorage::Attached::One
+ # proxy that provides the dynamic proxy to the associations and factory methods, like +#attach+.
#
# If the +:dependent+ option isn't set, the attachment will be purged
# (i.e. destroyed) whenever the record is destroyed.
def has_one_attached(name, dependent: :purge_later)
- define_method(name) do
- if instance_variable_defined?("@active_storage_attached_#{name}")
- instance_variable_get("@active_storage_attached_#{name}")
- else
- instance_variable_set("@active_storage_attached_#{name}", ActiveStorage::Attached::One.new(name, self))
+ class_eval <<-CODE, __FILE__, __LINE__ + 1
+ def #{name}
+ @active_storage_attached_#{name} ||= ActiveStorage::Attached::One.new("#{name}", self)
end
- end
+ CODE
has_one :"#{name}_attachment", -> { where(name: name) }, class_name: "ActiveStorage::Attachment", as: :record
has_one :"#{name}_blob", through: :"#{name}_attachment", class_name: "ActiveStorage::Blob", source: :blob
@@ -51,25 +49,23 @@ module ActiveStorage
#
# Gallery.where(user: Current.user).with_attached_photos
#
- # Under the covers, this relationship is implemented as a `has_many` association to a
- # `ActiveStorage::Attachment` record and a `has_many-through` association to a
- # `ActiveStorage::Blob` record. These associations are available as `photos_attachments`
- # and `photos_blobs`. But you shouldn't need to work with these associations directly in
+ # Under the covers, this relationship is implemented as a +has_many+ association to a
+ # ActiveStorage::Attachment record and a +has_many-through+ association to a
+ # ActiveStorage::Blob record. These associations are available as +photos_attachments+
+ # and +photos_blobs+. But you shouldn't need to work with these associations directly in
# most circumstances.
#
- # The system has been designed to having you go through the `ActiveStorage::Attached::Many`
- # proxy that provides the dynamic proxy to the associations and factory methods, like `#attach`.
+ # The system has been designed to having you go through the ActiveStorage::Attached::Many
+ # proxy that provides the dynamic proxy to the associations and factory methods, like +#attach+.
#
# If the +:dependent+ option isn't set, all the attachments will be purged
# (i.e. destroyed) whenever the record is destroyed.
def has_many_attached(name, dependent: :purge_later)
- define_method(name) do
- if instance_variable_defined?("@active_storage_attached_#{name}")
- instance_variable_get("@active_storage_attached_#{name}")
- else
- instance_variable_set("@active_storage_attached_#{name}", ActiveStorage::Attached::Many.new(name, self))
+ class_eval <<-CODE, __FILE__, __LINE__ + 1
+ def #{name}
+ @active_storage_attached_#{name} ||= ActiveStorage::Attached::Many.new("#{name}", self)
end
- end
+ CODE
has_many :"#{name}_attachments", -> { where(name: name) }, as: :record, class_name: "ActiveStorage::Attachment"
has_many :"#{name}_blobs", through: :"#{name}_attachments", class_name: "ActiveStorage::Blob", source: :blob
diff --git a/activestorage/lib/active_storage/attached/many.rb b/activestorage/lib/active_storage/attached/many.rb
index 1723756831..cc3e70ffe2 100644
--- a/activestorage/lib/active_storage/attached/many.rb
+++ b/activestorage/lib/active_storage/attached/many.rb
@@ -5,7 +5,7 @@ module ActiveStorage
# Returns all the associated attachment records.
#
- # All methods called on this proxy object that aren't listed here will automatically be delegated to `attachments`.
+ # All methods called on this proxy object that aren't listed here will automatically be delegated to +attachments+.
def attachments
record.public_send("#{name}_attachments")
end
diff --git a/activestorage/lib/active_storage/engine.rb b/activestorage/lib/active_storage/engine.rb
index d5bc70fc0c..a5562b32d3 100644
--- a/activestorage/lib/active_storage/engine.rb
+++ b/activestorage/lib/active_storage/engine.rb
@@ -5,6 +5,8 @@ require "active_storage"
module ActiveStorage
class Engine < Rails::Engine # :nodoc:
+ isolate_namespace ActiveStorage
+
config.active_storage = ActiveSupport::OrderedOptions.new
config.eager_load_namespaces << ActiveStorage
diff --git a/activestorage/lib/active_storage/service.rb b/activestorage/lib/active_storage/service.rb
index eb25e9f001..4dd6eb6045 100644
--- a/activestorage/lib/active_storage/service.rb
+++ b/activestorage/lib/active_storage/service.rb
@@ -59,43 +59,43 @@ module ActiveStorage
end
end
- # Upload the `io` to the `key` specified. If a `checksum` is provided, the service will
- # ensure a match when the upload has completed or raise an `ActiveStorage::IntegrityError`.
+ # Upload the +io+ to the +key+ specified. If a +checksum+ is provided, the service will
+ # ensure a match when the upload has completed or raise an ActiveStorage::IntegrityError.
def upload(key, io, checksum: nil)
raise NotImplementedError
end
- # Return the content of the file at the `key`.
+ # Return the content of the file at the +key+.
def download(key)
raise NotImplementedError
end
- # Delete the file at the `key`.
+ # Delete the file at the +key+.
def delete(key)
raise NotImplementedError
end
- # Return true if a file exists at the `key`.
+ # Return true if a file exists at the +key+.
def exist?(key)
raise NotImplementedError
end
- # Returns a signed, temporary URL for the file at the `key`. The URL will be valid for the amount
- # of seconds specified in `expires_in`. You most also provide the `disposition` (`:inline` or `:attachment`),
- # `filename`, and `content_type` that you wish the file to be served with on request.
+ # Returns a signed, temporary URL for the file at the +key+. The URL will be valid for the amount
+ # of seconds specified in +expires_in+. You most also provide the +disposition+ (+:inline+ or +:attachment+),
+ # +filename+, and +content_type+ that you wish the file to be served with on request.
def url(key, expires_in:, disposition:, filename:, content_type:)
raise NotImplementedError
end
- # Returns a signed, temporary URL that a direct upload file can be PUT to on the `key`.
- # The URL will be valid for the amount of seconds specified in `expires_in`.
- # You most also provide the `content_type`, `content_length`, and `checksum` of the file
+ # Returns a signed, temporary URL that a direct upload file can be PUT to on the +key+.
+ # The URL will be valid for the amount of seconds specified in +expires_in+.
+ # You most also provide the +content_type+, +content_length+, and +checksum+ of the file
# that will be uploaded. All these attributes will be validated by the service upon upload.
def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:)
raise NotImplementedError
end
- # Returns a Hash of headers for `url_for_direct_upload` requests.
+ # Returns a Hash of headers for +url_for_direct_upload+ requests.
def headers_for_direct_upload(key, filename:, content_type:, content_length:, checksum:)
{}
end
diff --git a/activestorage/lib/active_storage/service/azure_storage_service.rb b/activestorage/lib/active_storage/service/azure_storage_service.rb
index 2e0b20cce3..d1c62f7db1 100644
--- a/activestorage/lib/active_storage/service/azure_storage_service.rb
+++ b/activestorage/lib/active_storage/service/azure_storage_service.rb
@@ -4,7 +4,7 @@ require "azure/storage/core/auth/shared_access_signature"
module ActiveStorage
# Wraps the Microsoft Azure Storage Blob Service as a Active Storage service.
- # See `ActiveStorage::Service` for the generic API documentation that applies to all services.
+ # See ActiveStorage::Service for the generic API documentation that applies to all services.
class Service::AzureStorageService < Service
attr_reader :client, :path, :blobs, :container, :signer
diff --git a/activestorage/lib/active_storage/service/disk_service.rb b/activestorage/lib/active_storage/service/disk_service.rb
index cae7908126..9498761cc5 100644
--- a/activestorage/lib/active_storage/service/disk_service.rb
+++ b/activestorage/lib/active_storage/service/disk_service.rb
@@ -4,7 +4,7 @@ require "digest/md5"
require "active_support/core_ext/numeric/bytes"
module ActiveStorage
- # Wraps a local disk path as a Active Storage service. See `ActiveStorage::Service` for the generic API
+ # Wraps a local disk path as a Active Storage service. See ActiveStorage::Service for the generic API
# documentation that applies to all services.
class Service::DiskService < Service
attr_reader :root
diff --git a/activestorage/lib/active_storage/service/gcs_service.rb b/activestorage/lib/active_storage/service/gcs_service.rb
index ea4ec5a790..0707f26a74 100644
--- a/activestorage/lib/active_storage/service/gcs_service.rb
+++ b/activestorage/lib/active_storage/service/gcs_service.rb
@@ -2,7 +2,7 @@ require "google/cloud/storage"
require "active_support/core_ext/object/to_query"
module ActiveStorage
- # Wraps the Google Cloud Storage as a Active Storage service. See `ActiveStorage::Service` for the generic API
+ # Wraps the Google Cloud Storage as a Active Storage service. See ActiveStorage::Service for the generic API
# documentation that applies to all services.
class Service::GCSService < Service
attr_reader :client, :bucket
diff --git a/activestorage/lib/active_storage/service/mirror_service.rb b/activestorage/lib/active_storage/service/mirror_service.rb
index 2403eeb1e9..8491df4911 100644
--- a/activestorage/lib/active_storage/service/mirror_service.rb
+++ b/activestorage/lib/active_storage/service/mirror_service.rb
@@ -1,9 +1,9 @@
require "active_support/core_ext/module/delegation"
module ActiveStorage
- # Wraps a set of mirror services and provides a single `ActiveStorage::Service` object that will all
- # have the files uploaded to them. A `primary` service is designated to answer calls to `download`, `exists?`,
- # and `url`.
+ # Wraps a set of mirror services and provides a single ActiveStorage::Service object that will all
+ # have the files uploaded to them. A +primary+ service is designated to answer calls to +download+, +exists?+,
+ # and +url+.
class Service::MirrorService < Service
attr_reader :primary, :mirrors
@@ -20,15 +20,15 @@ module ActiveStorage
@primary, @mirrors = primary, mirrors
end
- # Upload the `io` to the `key` specified to all services. If a `checksum` is provided, all services will
- # ensure a match when the upload has completed or raise an `ActiveStorage::IntegrityError`.
+ # Upload the +io+ to the +key+ specified to all services. If a +checksum+ is provided, all services will
+ # ensure a match when the upload has completed or raise an ActiveStorage::IntegrityError.
def upload(key, io, checksum: nil)
each_service.collect do |service|
service.upload key, io.tap(&:rewind), checksum: checksum
end
end
- # Delete the file at the `key` on all services.
+ # Delete the file at the +key+ on all services.
def delete(key)
perform_across_services :delete, key
end
diff --git a/activestorage/lib/active_storage/service/s3_service.rb b/activestorage/lib/active_storage/service/s3_service.rb
index 5153f5db0d..b25eb409ef 100644
--- a/activestorage/lib/active_storage/service/s3_service.rb
+++ b/activestorage/lib/active_storage/service/s3_service.rb
@@ -3,7 +3,7 @@ require "active_support/core_ext/numeric/bytes"
module ActiveStorage
# Wraps the Amazon Simple Storage Service (S3) as a Active Storage service.
- # See `ActiveStorage::Service` for the generic API documentation that applies to all services.
+ # See ActiveStorage::Service for the generic API documentation that applies to all services.
class Service::S3Service < Service
attr_reader :client, :bucket, :upload_options
diff --git a/activestorage/lib/tasks/activestorage.rake b/activestorage/lib/tasks/activestorage.rake
index d9e240b141..7a573be596 100644
--- a/activestorage/lib/tasks/activestorage.rake
+++ b/activestorage/lib/tasks/activestorage.rake
@@ -1,6 +1,6 @@
namespace :activestorage do
desc "Copy over the migration needed to the application"
task install: :environment do
- Rake::Task["active_storage_engine:install:migrations"].invoke
+ Rake::Task["active_storage:install:migrations"].invoke
end
end
diff --git a/activestorage/test/controllers/blobs_controller_test.rb b/activestorage/test/controllers/blobs_controller_test.rb
new file mode 100644
index 0000000000..5ec353889c
--- /dev/null
+++ b/activestorage/test/controllers/blobs_controller_test.rb
@@ -0,0 +1,15 @@
+require "test_helper"
+require "database/setup"
+
+class ActiveStorage::BlobsControllerTest < ActionDispatch::IntegrationTest
+ setup do
+ @blob = create_image_blob filename: "racecar.jpg"
+ end
+
+ test "showing blob utilizes browser caching" do
+ get rails_blob_url(@blob)
+
+ assert_redirected_to(/racecar.jpg/)
+ assert_equal "max-age=300, private", @response.headers["Cache-Control"]
+ end
+end
diff --git a/activestorage/test/models/attachments_test.rb b/activestorage/test/models/attachments_test.rb
index 82256e1f44..58af5dce6e 100644
--- a/activestorage/test/models/attachments_test.rb
+++ b/activestorage/test/models/attachments_test.rb
@@ -1,13 +1,6 @@
require "test_helper"
require "database/setup"
-# ActiveRecord::Base.logger = Logger.new(STDOUT)
-
-class User < ActiveRecord::Base
- has_one_attached :avatar
- has_many_attached :highlights
-end
-
class ActiveStorage::AttachmentsTest < ActiveSupport::TestCase
include ActiveJob::TestHelper
diff --git a/activestorage/test/service/configurations.yml b/activestorage/test/service/configurations.yml
index d7aa672573..56ed37be5d 100644
--- a/activestorage/test/service/configurations.yml
+++ b/activestorage/test/service/configurations.yml
@@ -1,10 +1,10 @@
-s3:
- service: S3
- access_key_id: <%= ENV["AWS_ACCESS_KEY_ID"] %>
- secret_access_key: <%= ENV["AWS_SECRET_KEY"] %>
- region: us-east-2
- bucket: rails-ci-activestorage
-
+# s3:
+# service: S3
+# access_key_id: ""
+# secret_access_key: ""
+# region: ""
+# bucket: ""
+#
# gcs:
# service: GCS
# keyfile: {
diff --git a/activestorage/test/template/image_tag_test.rb b/activestorage/test/template/image_tag_test.rb
index 83c95c01a1..b285cd2e14 100644
--- a/activestorage/test/template/image_tag_test.rb
+++ b/activestorage/test/template/image_tag_test.rb
@@ -1,10 +1,6 @@
require "test_helper"
require "database/setup"
-class User < ActiveRecord::Base
- has_one_attached :avatar
-end
-
class ActiveStorage::ImageTagTest < ActionView::TestCase
tests ActionView::Helpers::AssetTagHelper
diff --git a/activestorage/test/test_helper.rb b/activestorage/test/test_helper.rb
index 50cc72cbe3..1190daa7b0 100644
--- a/activestorage/test/test_helper.rb
+++ b/activestorage/test/test_helper.rb
@@ -4,13 +4,15 @@ require "bundler/setup"
require "active_support"
require "active_support/test_case"
require "active_support/testing/autorun"
-require "byebug"
+
+begin
+ require "byebug"
+rescue LoadError
+end
require "active_job"
ActiveJob::Base.queue_adapter = :test
-ActiveJob::Base.logger = nil
-
-require "active_storage"
+ActiveJob::Base.logger = ActiveSupport::Logger.new(nil)
# Filter out Minitest backtrace while allowing backtrace from other libraries
# to be shown.
@@ -58,3 +60,8 @@ end
require "global_id"
GlobalID.app = "ActiveStorageExampleApp"
ActiveRecord::Base.send :include, GlobalID::Identification
+
+class User < ActiveRecord::Base
+ has_one_attached :avatar
+ has_many_attached :highlights
+end