From 92536c08d53c5d54f6c526bfdc5d854dd00a7a88 Mon Sep 17 00:00:00 2001
From: David Heinemeier Hansson <david@loudthinking.com>
Date: Mon, 24 Jul 2017 15:36:30 -0500
Subject: Document the rest of lib

---
 lib/active_storage/attached.rb               |  2 +-
 lib/active_storage/attached/macros.rb        | 18 ++++++++++++++++++
 lib/active_storage/attached/many.rb          | 16 ++++++++++------
 lib/active_storage/attached/one.rb           | 11 ++++++++---
 lib/active_storage/service.rb                | 12 ++++++++++++
 lib/active_storage/service/disk_service.rb   |  2 ++
 lib/active_storage/service/gcs_service.rb    |  2 ++
 lib/active_storage/service/mirror_service.rb |  6 ++++++
 lib/active_storage/service/s3_service.rb     |  2 ++
 9 files changed, 61 insertions(+), 10 deletions(-)

(limited to 'lib')

diff --git a/lib/active_storage/attached.rb b/lib/active_storage/attached.rb
index 8bec129a1a..4644d74bcc 100644
--- a/lib/active_storage/attached.rb
+++ b/lib/active_storage/attached.rb
@@ -4,7 +4,7 @@ require "active_storage/attachment"
 require "action_dispatch/http/upload"
 require "active_support/core_ext/module/delegation"
 
-# Abstract baseclass for the particular `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 ActiveStorage::Attached
   attr_reader :name, :record
diff --git a/lib/active_storage/attached/macros.rb b/lib/active_storage/attached/macros.rb
index 11f88f16e5..89297e5bdf 100644
--- a/lib/active_storage/attached/macros.rb
+++ b/lib/active_storage/attached/macros.rb
@@ -9,6 +9,15 @@ module ActiveStorage::Attached::Macros
   # 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
+  # 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`.
+  #
   # 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)
@@ -38,6 +47,15 @@ module ActiveStorage::Attached::Macros
   #
   #   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
+  # 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`.
+  #
   # 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)
diff --git a/lib/active_storage/attached/many.rb b/lib/active_storage/attached/many.rb
index ea4aade5d7..035cd9c091 100644
--- a/lib/active_storage/attached/many.rb
+++ b/lib/active_storage/attached/many.rb
@@ -1,24 +1,28 @@
-# Representation of multiple attachments to a model.
+# Decorated proxy object representing of multiple attachments to a model.
 class ActiveStorage::Attached::Many < ActiveStorage::Attached
   delegate_missing_to :attachments
 
   # Returns all the associated attachment records.
   #
-  # You don't have to call this method to access the attachments' methods as
-  # they are all available at the model level.
+  # 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
 
-  # Associates one or several attachments with the current record, saving
-  # them to the database.
+  # Associates one or several attachments with the current record, saving them to the database.
+  # Examples:
+  #
+  #   document.images.attach(params[:images]) # Array of ActionDispatch::Http::UploadedFile objects
+  #   document.images.attach(params[:signed_blob_id]) # Signed reference to blob from direct upload
+  #   document.images.attach(io: File.open("~/racecar.jpg"), filename: "racecar.jpg", content_type: "image/jpg")
+  #   document.images.attach([ first_blob, second_blob ])
   def attach(*attachables)
     attachables.flatten.collect do |attachable|
       attachments.create!(name: name, blob: create_blob_from(attachable))
     end
   end
 
-  # Checks the presence of attachments.
+  # Returns true if any attachments has been made.
   #
   #   class Gallery < ActiveRecord::Base
   #     has_many_attached :photos
diff --git a/lib/active_storage/attached/one.rb b/lib/active_storage/attached/one.rb
index d255412842..0c522e856e 100644
--- a/lib/active_storage/attached/one.rb
+++ b/lib/active_storage/attached/one.rb
@@ -10,14 +10,19 @@ class ActiveStorage::Attached::One < ActiveStorage::Attached
     record.public_send("#{name}_attachment")
   end
 
-  # Associates a given attachment with the current record, saving it to the
-  # database.
+  # Associates a given attachment with the current record, saving it to the database.
+  # Examples:
+  #
+  #   person.avatar.attach(params[:avatar]) # ActionDispatch::Http::UploadedFile object
+  #   person.avatar.attach(params[:signed_blob_id]) # Signed reference to blob from direct upload
+  #   person.avatar.attach(io: File.open("~/face.jpg"), filename: "face.jpg", content_type: "image/jpg")
+  #   person.avatar.attach(avatar_blob) # ActiveStorage::Blob object
   def attach(attachable)
     write_attachment \
       ActiveStorage::Attachment.create!(record: record, name: name, blob: create_blob_from(attachable))
   end
 
-  # Checks the presence of the attachment.
+  # Returns true if an attachment has been made.
   #
   #   class User < ActiveRecord::Base
   #     has_one_attached :avatar
diff --git a/lib/active_storage/service.rb b/lib/active_storage/service.rb
index 127895406f..e6361318a8 100644
--- a/lib/active_storage/service.rb
+++ b/lib/active_storage/service.rb
@@ -58,26 +58,38 @@ class ActiveStorage::Service
     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`.
   def upload(key, io, checksum: nil)
     raise NotImplementedError
   end
 
+  # Return the content of the file at the `key`.
   def download(key)
     raise NotImplementedError
   end
 
+  # Delete the file at the `key`.
   def delete(key)
     raise NotImplementedError
   end
 
+  # 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.
   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
+  # 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
diff --git a/lib/active_storage/service/disk_service.rb b/lib/active_storage/service/disk_service.rb
index 3cde203a31..7e2079385f 100644
--- a/lib/active_storage/service/disk_service.rb
+++ b/lib/active_storage/service/disk_service.rb
@@ -3,6 +3,8 @@ require "pathname"
 require "digest/md5"
 require "active_support/core_ext/numeric/bytes"
 
+# Wraps a local disk path as a Active Storage service. See `ActiveStorage::Service` for the generic API
+# documentation that applies to all services.
 class ActiveStorage::Service::DiskService < ActiveStorage::Service
   attr_reader :root
 
diff --git a/lib/active_storage/service/gcs_service.rb b/lib/active_storage/service/gcs_service.rb
index 4632e5f820..d681a3dc45 100644
--- a/lib/active_storage/service/gcs_service.rb
+++ b/lib/active_storage/service/gcs_service.rb
@@ -1,6 +1,8 @@
 require "google/cloud/storage"
 require "active_support/core_ext/object/to_query"
 
+# Wraps the Google Cloud Storage as a Active Storage service. See `ActiveStorage::Service` for the generic API
+# documentation that applies to all services.
 class ActiveStorage::Service::GCSService < ActiveStorage::Service
   attr_reader :client, :bucket
 
diff --git a/lib/active_storage/service/mirror_service.rb b/lib/active_storage/service/mirror_service.rb
index 54465cad05..7c407f2730 100644
--- a/lib/active_storage/service/mirror_service.rb
+++ b/lib/active_storage/service/mirror_service.rb
@@ -1,5 +1,8 @@
 require "active_support/core_ext/module/delegation"
 
+# 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 ActiveStorage::Service::MirrorService < ActiveStorage::Service
   attr_reader :primary, :mirrors
 
@@ -16,12 +19,15 @@ class ActiveStorage::Service::MirrorService < ActiveStorage::Service
     @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`.
   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.
   def delete(key)
     perform_across_services :delete, key
   end
diff --git a/lib/active_storage/service/s3_service.rb b/lib/active_storage/service/s3_service.rb
index 72ff9f3f36..c21977044d 100644
--- a/lib/active_storage/service/s3_service.rb
+++ b/lib/active_storage/service/s3_service.rb
@@ -1,6 +1,8 @@
 require "aws-sdk"
 require "active_support/core_ext/numeric/bytes"
 
+# 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.
 class ActiveStorage::Service::S3Service < ActiveStorage::Service
   attr_reader :client, :bucket, :upload_options
 
-- 
cgit v1.2.3