aboutsummaryrefslogtreecommitdiffstats
path: root/activestorage/lib/active_storage/attached/changes/create_one.rb
diff options
context:
space:
mode:
authorGeorge Claghorn <george.claghorn@gmail.com>2018-07-07 23:25:33 -0400
committerGitHub <noreply@github.com>2018-07-07 23:25:33 -0400
commite8682c5bf051517b0b265e446aa1a7eccfd47bf7 (patch)
treecc04c8a28113bc0fa3748fdc6035d487e3e16af7 /activestorage/lib/active_storage/attached/changes/create_one.rb
parent0b534cd1c814a4db2d0aa283981f1d55e5e62d25 (diff)
downloadrails-e8682c5bf051517b0b265e446aa1a7eccfd47bf7.tar.gz
rails-e8682c5bf051517b0b265e446aa1a7eccfd47bf7.tar.bz2
rails-e8682c5bf051517b0b265e446aa1a7eccfd47bf7.zip
Store newly-uploaded files on save rather than assignment
Diffstat (limited to 'activestorage/lib/active_storage/attached/changes/create_one.rb')
-rw-r--r--activestorage/lib/active_storage/attached/changes/create_one.rb65
1 files changed, 65 insertions, 0 deletions
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..bb59a651ba
--- /dev/null
+++ b/activestorage/lib/active_storage/attached/changes/create_one.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+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 "Could not find or build blob: expected attachable, got #{attachable.inspect}"
+ end
+ end
+ end
+end