1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Merge pull request #15 from robin850/documentation

Add some documentation
This commit is contained in:
David Heinemeier Hansson 2017-07-08 19:00:42 +02:00 committed by GitHub
commit 97bd958d91
6 changed files with 100 additions and 5 deletions

View file

@ -1,7 +1,18 @@
module ActiveStorage::Attached::Macros module ActiveStorage::Attached::Macros
# Specifies the relation between a single attachment and the model.
#
# class User < ActiveRecord::Base
# has_one_attached :avatar
# end
#
# There is no column defined on the model side, Active Storage takes
# care of the mapping between your records and the attachment.
#
# 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) def has_one_attached(name, dependent: :purge_later)
define_method(name) do define_method(name) do
instance_variable_get("@active_storage_attached_#{name}") || instance_variable_get("@active_storage_attached_#{name}") ||
instance_variable_set("@active_storage_attached_#{name}", ActiveStorage::Attached::One.new(name, self)) instance_variable_set("@active_storage_attached_#{name}", ActiveStorage::Attached::One.new(name, self))
end end
@ -10,9 +21,20 @@ module ActiveStorage::Attached::Macros
end end
end end
# Specifies the relation between multiple attachments and the model.
#
# class Gallery < ActiveRecord::Base
# has_many_attached :photos
# end
#
# There are no columns defined on the model side, Active Storage takes
# care of the mapping between your records and the attachments.
#
# 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) def has_many_attached(name, dependent: :purge_later)
define_method(name) do define_method(name) do
instance_variable_get("@active_storage_attached_#{name}") || instance_variable_get("@active_storage_attached_#{name}") ||
instance_variable_set("@active_storage_attached_#{name}", ActiveStorage::Attached::Many.new(name, self)) instance_variable_set("@active_storage_attached_#{name}", ActiveStorage::Attached::Many.new(name, self))
end end

View file

@ -1,20 +1,36 @@
# Representation of multiple attachments to a model.
class ActiveStorage::Attached::Many < ActiveStorage::Attached class ActiveStorage::Attached::Many < ActiveStorage::Attached
delegate_missing_to :attachments 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.
def attachments def attachments
@attachments ||= ActiveStorage::Attachment.where(record_gid: record.to_gid.to_s, name: name) @attachments ||= ActiveStorage::Attachment.where(record_gid: record.to_gid.to_s, name: name)
end end
# Associates one or several attachments with the current record, saving
# them to the database.
def attach(*attachables) def attach(*attachables)
@attachments = attachments | Array(attachables).flatten.collect do |attachable| @attachments = attachments | Array(attachables).flatten.collect do |attachable|
ActiveStorage::Attachment.create!(record_gid: record.to_gid.to_s, name: name, blob: create_blob_from(attachable)) ActiveStorage::Attachment.create!(record_gid: record.to_gid.to_s, name: name, blob: create_blob_from(attachable))
end end
end end
# Checks the presence of attachments.
#
# class Gallery < ActiveRecord::Base
# has_many_attached :photos
# end
#
# Gallery.new.photos.attached? # => false
def attached? def attached?
attachments.any? attachments.any?
end end
# Directly purges each associated attachment (i.e. destroys the blobs and
# attachments and deletes the files on the service).
def purge def purge
if attached? if attached?
attachments.each(&:purge) attachments.each(&:purge)
@ -22,6 +38,7 @@ class ActiveStorage::Attached::Many < ActiveStorage::Attached
end end
end end
# Purges each associated attachment through the queuing system.
def purge_later def purge_later
if attached? if attached?
attachments.each(&:purge_later) attachments.each(&:purge_later)

View file

@ -1,18 +1,34 @@
# Representation of a single attachment to a model.
class ActiveStorage::Attached::One < ActiveStorage::Attached class ActiveStorage::Attached::One < ActiveStorage::Attached
delegate_missing_to :attachment delegate_missing_to :attachment
# Returns the associated attachment record.
#
# You don't have to call this method to access the attachment's methods as
# they are all available at the model level.
def attachment def attachment
@attachment ||= ActiveStorage::Attachment.find_by(record_gid: record.to_gid.to_s, name: name) @attachment ||= ActiveStorage::Attachment.find_by(record_gid: record.to_gid.to_s, name: name)
end end
# Associates a given attachment with the current record, saving it to the
# database.
def attach(attachable) def attach(attachable)
@attachment = ActiveStorage::Attachment.create!(record_gid: record.to_gid.to_s, name: name, blob: create_blob_from(attachable)) @attachment = ActiveStorage::Attachment.create!(record_gid: record.to_gid.to_s, name: name, blob: create_blob_from(attachable))
end end
# Checks the presence of the attachment.
#
# class User < ActiveRecord::Base
# has_one_attached :avatar
# end
#
# User.new.avatar.attached? # => false
def attached? def attached?
attachment.present? attachment.present?
end end
# Directly purges the attachment (i.e. destroys the blob and
# attachment and deletes the file on the service).
def purge def purge
if attached? if attached?
attachment.purge attachment.purge
@ -20,6 +36,7 @@ class ActiveStorage::Attached::One < ActiveStorage::Attached
end end
end end
# Purges the attachment through the queuing system.
def purge_later def purge_later
if attached? if attached?
attachment.purge_later attachment.purge_later

View file

@ -4,11 +4,21 @@ require "active_storage/verified_key_with_expiration"
require "active_support/core_ext/object/inclusion" require "active_support/core_ext/object/inclusion"
# This controller is a wrapper around local file downloading. It allows you to
# make abstraction of the URL generation logic and to serve files with expiry
# if you are using the +Disk+ service.
#
# By default, mounting the Active Storage engine inside your application will
# define a +/rails/blobs/:encoded_key+ route that will reference this controller's
# +show+ action and will be used to serve local files.
#
# A URL for an attachment can be generated through its +#url+ method, that
# will use the aforementioned route.
class ActiveStorage::DiskController < ActionController::Base class ActiveStorage::DiskController < ActionController::Base
def show def show
if key = decode_verified_key if key = decode_verified_key
blob = ActiveStorage::Blob.find_by!(key: key) blob = ActiveStorage::Blob.find_by!(key: key)
if stale?(etag: blob.checksum) if stale?(etag: blob.checksum)
send_data blob.download, filename: blob.filename, type: blob.content_type, disposition: disposition_param send_data blob.download, filename: blob.filename, type: blob.content_type, disposition: disposition_param
end end

View file

@ -1,4 +1,4 @@
class ActiveStorageCreateTables < ActiveRecord::Migration[5.1] class ActiveStorageCreateTables < ActiveRecord::Migration[5.1] # :nodoc:
def change def change
create_table :active_storage_blobs do |t| create_table :active_storage_blobs do |t|
t.string :key t.string :key

View file

@ -1,4 +1,34 @@
# Abstract class serving as an interface for concrete services. # Abstract class serving as an interface for concrete services.
#
# The available services are:
#
# * +Disk+, to manage attachments saved directly on the hard drive.
# * +GCS+, to manage attachments through Google Cloud Storage.
# * +S3+, to manage attachments through Amazon S3.
# * +Mirror+, to be able to use several services to manage attachments.
#
# Inside a Rails application, you can set-up your services through the
# generated <tt>config/storage_services.yml</tt> file and reference one
# of the aforementioned constant under the +service+ key. For example:
#
# local:
# service: Disk
# root: <%= Rails.root.join("storage") %>
#
# You can checkout the service's constructor to know which keys are required.
#
# Then, in your application's configuration, you can specify the service to
# use like this:
#
# config.active_storage.service = :local
#
# If you are using Active Storage outside of a Ruby on Rails application, you
# can configure the service to use like this:
#
# ActiveStorage::Blob.service = ActiveStorage::Service.configure(
# :Disk,
# root: Pathname("/foo/bar/storage")
# )
class ActiveStorage::Service class ActiveStorage::Service
class ActiveStorage::IntegrityError < StandardError; end class ActiveStorage::IntegrityError < StandardError; end
@ -11,7 +41,6 @@ class ActiveStorage::Service
end end
end end
def upload(key, io, checksum: nil) def upload(key, io, checksum: nil)
raise NotImplementedError raise NotImplementedError
end end