1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
# 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)
record.public_send("#{name}_blob=", blob)
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
|