module Shrine::UploadedFile::InstanceMethods

Attributes

id[R]

The location where the file was uploaded to the storage.

metadata[R]

A hash of file metadata that was extracted during upload.

storage_key[R]

The identifier of the storage the file is uploaded to.

Public Class Methods

new(data) click to toggle source

Initializes the uploaded file with the given data hash.

# File lib/shrine/uploaded_file.rb, line 35
def initialize(data)
  @id          = data[:id]              || data["id"]
  @storage_key = data[:storage]&.to_sym || data["storage"]&.to_sym
  @metadata    = data[:metadata]        || data["metadata"]        || {}

  fail Error, "#{data.inspect} isn't valid uploaded file data" unless @id && @storage_key

  storage # ensure storage is registered
end

Public Instance Methods

==(other) click to toggle source

Returns true if the other UploadedFile is uploaded to the same storage and it has the same id.

# File lib/shrine/uploaded_file.rb, line 226
def ==(other)
  self.class       == other.class       &&
  self.id          == other.id          &&
  self.storage_key == other.storage_key
end
Also aliased as: eql?
[](key) click to toggle source

Shorthand for accessing metadata values.

# File lib/shrine/uploaded_file.rb, line 71
def [](key)
  metadata[key]
end
as_json(*args) click to toggle source

Conform to ActiveSupport’s JSON interface.

# File lib/shrine/uploaded_file.rb, line 215
def as_json(*args)
  data
end
close() click to toggle source

Part of complying to the IO interface. It delegates to the internally opened IO object.

# File lib/shrine/uploaded_file.rb, line 171
def close
  io.close if opened?
  @io = nil
end
content_type()
Alias for: mime_type
data() click to toggle source

Returns serializable hash representation of the uploaded file.

# File lib/shrine/uploaded_file.rb, line 220
def data
  { "id" => id, "storage" => storage_key.to_s, "metadata" => metadata }
end
delete() click to toggle source

Calls ‘#delete` on the storage, which deletes the file from the storage.

# File lib/shrine/uploaded_file.rb, line 199
def delete
  storage.delete(id)
end
download(**options) { |tempfile| ... } click to toggle source

Streams content into a newly created Tempfile and returns it.

If a block is given, the opened Tempfile object is yielded to the block, and at the end of the block it’s automatically closed and deleted. In this case the return value of the method is the block return value.

If no block is given, the opened Tempfile is returned.

uploaded_file.download
#=> #<File:/var/folders/.../20180302-33119-1h1vjbq.jpg>

# or

uploaded_file.download { |tempfile| tempfile.read } # tempfile is deleted
# File lib/shrine/uploaded_file.rb, line 121
def download(**options)
  tempfile = Tempfile.new(["shrine", ".#{extension}"], binmode: true)
  stream(tempfile, **options)
  tempfile.open

  block_given? ? yield(tempfile) : tempfile
ensure
  tempfile.close! if ($! || block_given?) && tempfile
end
eof?() click to toggle source

Part of complying to the IO interface. It delegates to the internally opened IO object.

# File lib/shrine/uploaded_file.rb, line 159
def eof?
  io.eof?
end
eql?(other)
Alias for: ==
exists?() click to toggle source

Calls ‘#exists?` on the storage, which checks whether the file exists on the storage.

# File lib/shrine/uploaded_file.rb, line 188
def exists?
  storage.exists?(id)
end
extension() click to toggle source

The extension derived from id if present, otherwise it’s derived from original_filename.

# File lib/shrine/uploaded_file.rb, line 52
def extension
  identifier = id =~ URI::DEFAULT_PARSER.make_regexp ? id.sub(/\?.+$/, "") : id # strip query params for shrine-url
  result = File.extname(identifier)[1..-1]
  result ||= File.extname(original_filename.to_s)[1..-1]
  result.downcase if result
end
hash() click to toggle source

Enables using UploadedFile objects as hash keys.

# File lib/shrine/uploaded_file.rb, line 234
def hash
  [id, storage_key].hash
end
inspect() click to toggle source

Returns simplified inspect output.

# File lib/shrine/uploaded_file.rb, line 254
def inspect
  "#<#{self.class.inspect} storage=#{storage_key.inspect} id=#{id.inspect} metadata=#{metadata.inspect}>"
end
mime_type() click to toggle source

The MIME type of the uploaded file.

# File lib/shrine/uploaded_file.rb, line 65
def mime_type
  metadata["mime_type"]
end
Also aliased as: content_type
open(**options) { |io| ... } click to toggle source

Calls ‘#open` on the storage to open the uploaded file for reading. Most storages will return a lazy IO object which dynamically retrieves file content from the storage as the object is being read.

If a block is given, the opened IO object is yielded to the block, and at the end of the block it’s automatically closed. In this case the return value of the method is the block return value.

If no block is given, the opened IO object is returned.

uploaded_file.open #=> IO object returned by the storage
uploaded_file.read #=> "..."
uploaded_file.close

# or

uploaded_file.open { |io| io.read } # the IO is automatically closed
# File lib/shrine/uploaded_file.rb, line 92
def open(**options)
  @io.close if @io
  @io = _open(**options)

  return @io unless block_given?

  begin
    yield @io
  ensure
    close
    @io = nil
  end
end
opened?() click to toggle source

Returns whether the file has already been opened.

# File lib/shrine/uploaded_file.rb, line 177
def opened?
  !!@io
end
original_filename() click to toggle source

The filename that was extracted from the uploaded file.

# File lib/shrine/uploaded_file.rb, line 46
def original_filename
  metadata["filename"]
end
read(*args) click to toggle source

Part of complying to the IO interface. It delegates to the internally opened IO object.

# File lib/shrine/uploaded_file.rb, line 153
def read(*args)
  io.read(*args)
end
replace(io, **options) click to toggle source

Uploads a new file to this file’s location and returns it.

# File lib/shrine/uploaded_file.rb, line 193
def replace(io, **options)
  uploader.upload(io, **options, location: id)
end
rewind() click to toggle source

Part of complying to the IO interface. It delegates to the internally opened IO object.

# File lib/shrine/uploaded_file.rb, line 165
def rewind
  io.rewind
end
shrine_class() click to toggle source

Returns the Shrine class that this file’s class is namespaced under.

# File lib/shrine/uploaded_file.rb, line 249
def shrine_class
  self.class.shrine_class
end
size() click to toggle source

The filesize of the uploaded file.

# File lib/shrine/uploaded_file.rb, line 60
def size
  (@io && @io.size) || (metadata["size"] && Integer(metadata["size"]))
end
storage() click to toggle source

Returns the storage that this file was uploaded to.

# File lib/shrine/uploaded_file.rb, line 244
def storage
  shrine_class.find_storage(storage_key)
end
stream(destination, **options) click to toggle source

Streams uploaded file content into the specified destination. The destination object is given directly to ‘IO.copy_stream`, so it can be either a path on disk or an object that responds to `#write`.

If the uploaded file is already opened, it will be simply rewinded after streaming finishes. Otherwise the uploaded file is opened and then closed after streaming.

uploaded_file.stream(StringIO.new)
# or
uploaded_file.stream("/path/to/destination")
# File lib/shrine/uploaded_file.rb, line 142
def stream(destination, **options)
  if opened?
    IO.copy_stream(io, destination)
    io.rewind
  else
    open(**options) { |io| IO.copy_stream(io, destination) }
  end
end
to_io() click to toggle source

Returns an opened IO object for the uploaded file.

# File lib/shrine/uploaded_file.rb, line 204
def to_io
  io
end
to_json(*args) click to toggle source

Returns the data hash in the JSON format. Suitable for storing in a database column or passing to a background job.

# File lib/shrine/uploaded_file.rb, line 210
def to_json(*args)
  data.to_json(*args)
end
uploader() click to toggle source

Returns an uploader object for the corresponding storage.

# File lib/shrine/uploaded_file.rb, line 239
def uploader
  shrine_class.new(storage_key)
end
url(**options) click to toggle source

Calls ‘#url` on the storage, forwarding any given URL options.

# File lib/shrine/uploaded_file.rb, line 182
def url(**options)
  storage.url(id, **options)
end

Private Instance Methods

_open(**options) click to toggle source
# File lib/shrine/uploaded_file.rb, line 266
def _open(**options)
  storage.open(id, **options)
end
io() click to toggle source

Returns an opened IO object for the uploaded file by calling ‘#open` on the storage.

# File lib/shrine/uploaded_file.rb, line 262
def io
  @io ||= _open
end