class ActiveStorage::Attached::Changes::CreateOne

:nodoc:

def attachment

def attachment
  @attachment ||= find_or_build_attachment
end

def attachment_service_name

def attachment_service_name
  record.attachment_reflections[name].options[:service_name]
end

def blob

def blob
  @blob ||= find_or_build_blob
end

def build_attachment

def build_attachment
  ActiveStorage::Attachment.new(record: record, name: name, blob: blob)
end

def find_attachment

def find_attachment
  if record.public_send("#{name}_blob") == blob
    record.public_send("#{name}_attachment")
  end
end

def find_or_build_attachment

def find_or_build_attachment
  find_attachment || build_attachment
end

def find_or_build_blob

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,
      record: record,
      service_name: attachment_service_name
    )
  when Hash
    ActiveStorage::Blob.build_after_unfurling(
      **attachable.reverse_merge(
        record: record,
        service_name: attachment_service_name
      ).symbolize_keys
    )
  when String
    ActiveStorage::Blob.find_signed!(attachable, record: record)
  else
    raise ArgumentError, "Could not find or build blob: expected attachable, got #{attachable.inspect}"
  end
end

def initialize(name, record, attachable)

def initialize(name, record, attachable)
  @name, @record, @attachable = name, record, attachable
  blob.identify_without_saving
end

def save

def save
  record.public_send("#{name}_attachment=", attachment)
  record.public_send("#{name}_blob=", blob)
end

def upload

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