aboutsummaryrefslogtreecommitdiffstats
path: root/activestorage/lib/active_storage/attached/changes
diff options
context:
space:
mode:
Diffstat (limited to 'activestorage/lib/active_storage/attached/changes')
-rw-r--r--activestorage/lib/active_storage/attached/changes/create_many.rb46
-rw-r--r--activestorage/lib/active_storage/attached/changes/create_one.rb68
-rw-r--r--activestorage/lib/active_storage/attached/changes/create_one_of_many.rb10
-rw-r--r--activestorage/lib/active_storage/attached/changes/delete_many.rb23
-rw-r--r--activestorage/lib/active_storage/attached/changes/delete_one.rb19
5 files changed, 166 insertions, 0 deletions
diff --git a/activestorage/lib/active_storage/attached/changes/create_many.rb b/activestorage/lib/active_storage/attached/changes/create_many.rb
new file mode 100644
index 0000000000..a7a8553e0f
--- /dev/null
+++ b/activestorage/lib/active_storage/attached/changes/create_many.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+module ActiveStorage
+ class Attached::Changes::CreateMany #:nodoc:
+ attr_reader :name, :record, :attachables
+
+ def initialize(name, record, attachables)
+ @name, @record, @attachables = name, record, Array(attachables)
+ end
+
+ def attachments
+ @attachments ||= subchanges.collect(&:attachment)
+ end
+
+ def blobs
+ @blobs ||= subchanges.collect(&:blob)
+ end
+
+ def upload
+ subchanges.each(&:upload)
+ end
+
+ def save
+ assign_associated_attachments
+ reset_associated_blobs
+ end
+
+ private
+ def subchanges
+ @subchanges ||= attachables.collect { |attachable| build_subchange_from(attachable) }
+ end
+
+ def build_subchange_from(attachable)
+ ActiveStorage::Attached::Changes::CreateOneOfMany.new(name, record, attachable)
+ end
+
+
+ def assign_associated_attachments
+ record.public_send("#{name}_attachments=", attachments)
+ end
+
+ def reset_associated_blobs
+ record.public_send("#{name}_blobs").reset
+ end
+ end
+end
diff --git a/activestorage/lib/active_storage/attached/changes/create_one.rb b/activestorage/lib/active_storage/attached/changes/create_one.rb
new file mode 100644
index 0000000000..5812fd2b08
--- /dev/null
+++ b/activestorage/lib/active_storage/attached/changes/create_one.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+require "action_dispatch"
+require "action_dispatch/http/upload"
+
+module ActiveStorage
+ class Attached::Changes::CreateOne #:nodoc:
+ attr_reader :name, :record, :attachable
+
+ def initialize(name, record, attachable)
+ @name, @record, @attachable = name, record, attachable
+ end
+
+ def attachment
+ @attachment ||= find_or_build_attachment
+ end
+
+ def blob
+ @blob ||= find_or_build_blob
+ end
+
+ def upload
+ case attachable
+ when ActionDispatch::Http::UploadedFile, Rack::Test::UploadedFile
+ blob.upload_without_unfurling(attachable.open)
+ when Hash
+ blob.upload_without_unfurling(attachable.fetch(:io))
+ end
+ end
+
+ def save
+ record.public_send("#{name}_attachment=", attachment)
+ end
+
+ private
+ def find_or_build_attachment
+ find_attachment || build_attachment
+ end
+
+ def find_attachment
+ if record.public_send("#{name}_blob") == blob
+ record.public_send("#{name}_attachment")
+ end
+ end
+
+ def build_attachment
+ ActiveStorage::Attachment.new(record: record, name: name, blob: blob)
+ end
+
+ def find_or_build_blob
+ case attachable
+ when ActiveStorage::Blob
+ attachable
+ when ActionDispatch::Http::UploadedFile, Rack::Test::UploadedFile
+ ActiveStorage::Blob.build_after_unfurling \
+ io: attachable.open,
+ filename: attachable.original_filename,
+ content_type: attachable.content_type
+ when Hash
+ ActiveStorage::Blob.build_after_unfurling(attachable)
+ when String
+ ActiveStorage::Blob.find_signed(attachable)
+ else
+ raise ArgumentError, "Could not find or build blob: expected attachable, got #{attachable.inspect}"
+ end
+ end
+ end
+end
diff --git a/activestorage/lib/active_storage/attached/changes/create_one_of_many.rb b/activestorage/lib/active_storage/attached/changes/create_one_of_many.rb
new file mode 100644
index 0000000000..7268e87316
--- /dev/null
+++ b/activestorage/lib/active_storage/attached/changes/create_one_of_many.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+module ActiveStorage
+ class Attached::Changes::CreateOneOfMany < Attached::Changes::CreateOne #:nodoc:
+ private
+ def find_attachment
+ record.public_send("#{name}_attachments").detect { |attachment| attachment.blob_id == blob.id }
+ end
+ end
+end
diff --git a/activestorage/lib/active_storage/attached/changes/delete_many.rb b/activestorage/lib/active_storage/attached/changes/delete_many.rb
new file mode 100644
index 0000000000..6cbd1158dc
--- /dev/null
+++ b/activestorage/lib/active_storage/attached/changes/delete_many.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module ActiveStorage
+ class Attached::Changes::DeleteMany #:nodoc:
+ attr_reader :name, :record
+
+ def initialize(name, record)
+ @name, @record = name, record
+ end
+
+ def attachments
+ ActiveStorage::Attachment.none
+ end
+
+ def blobs
+ ActiveStorage::Blob.none
+ end
+
+ def save
+ record.public_send("#{name}_attachments=", [])
+ end
+ end
+end
diff --git a/activestorage/lib/active_storage/attached/changes/delete_one.rb b/activestorage/lib/active_storage/attached/changes/delete_one.rb
new file mode 100644
index 0000000000..2f7d356613
--- /dev/null
+++ b/activestorage/lib/active_storage/attached/changes/delete_one.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module ActiveStorage
+ class Attached::Changes::DeleteOne #:nodoc:
+ attr_reader :name, :record
+
+ def initialize(name, record)
+ @name, @record = name, record
+ end
+
+ def attachment
+ nil
+ end
+
+ def save
+ record.public_send("#{name}_attachment=", nil)
+ end
+ end
+end