Module: Shrine::UploadedFile::InstanceMethods

Included in:
Shrine::UploadedFile
Defined in:
lib/shrine/uploaded_file.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#idObject (readonly)

The location where the file was uploaded to the storage.


26
27
28
# File 'lib/shrine/uploaded_file.rb', line 26

def id
  @id
end

#metadataObject (readonly)

A hash of file metadata that was extracted during upload.


32
33
34
# File 'lib/shrine/uploaded_file.rb', line 32

def 
  @metadata
end

#storage_keyObject (readonly)

The identifier of the storage the file is uploaded to.


29
30
31
# File 'lib/shrine/uploaded_file.rb', line 29

def storage_key
  @storage_key
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?

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


224
225
226
227
228
# File 'lib/shrine/uploaded_file.rb', line 224

def ==(other)
  self.class       == other.class       &&
  self.id          == other.id          &&
  self.storage_key == other.storage_key
end

#[](key) ⇒ Object

Shorthand for accessing metadata values.


70
71
72
# File 'lib/shrine/uploaded_file.rb', line 70

def [](key)
  [key]
end

#as_json(*args) ⇒ Object

Conform to ActiveSupport's JSON interface.


213
214
215
# File 'lib/shrine/uploaded_file.rb', line 213

def as_json(*args)
  data
end

#closeObject

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


170
171
172
# File 'lib/shrine/uploaded_file.rb', line 170

def close
  io.close if opened?
end

#dataObject

Returns serializable hash representation of the uploaded file.


218
219
220
# File 'lib/shrine/uploaded_file.rb', line 218

def data
  { "id" => id, "storage" => storage_key.to_s, "metadata" =>  }
end

#deleteObject

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


197
198
199
# File 'lib/shrine/uploaded_file.rb', line 197

def delete
  storage.delete(id)
end

#download(**options) ⇒ Object

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

120
121
122
123
124
125
126
127
128
# File 'lib/shrine/uploaded_file.rb', line 120

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?Boolean

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

Returns:

  • (Boolean)

158
159
160
# File 'lib/shrine/uploaded_file.rb', line 158

def eof?
  io.eof?
end

#exists?Boolean

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

Returns:

  • (Boolean)

186
187
188
# File 'lib/shrine/uploaded_file.rb', line 186

def exists?
  storage.exists?(id)
end

#extensionObject

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


52
53
54
55
56
# File 'lib/shrine/uploaded_file.rb', line 52

def extension
  result = File.extname(id)[1..-1] || File.extname(original_filename.to_s)[1..-1]
  result.sub!(/\?.+$/, "") if result && id =~ URI::regexp # strip query params for shrine-url
  result.downcase if result
end

#hashObject

Enables using UploadedFile objects as hash keys.


232
233
234
# File 'lib/shrine/uploaded_file.rb', line 232

def hash
  [id, storage_key].hash
end

#initialize(data) ⇒ Object

Initializes the uploaded file with the given data hash.


35
36
37
38
39
40
41
42
43
# 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

#inspectObject

Returns simplified inspect output.


252
253
254
# File 'lib/shrine/uploaded_file.rb', line 252

def inspect
  "#<#{self.class.inspect} storage=#{storage_key.inspect} id=#{id.inspect} metadata=#{.inspect}>"
end

#mime_typeObject Also known as: content_type

The MIME type of the uploaded file.


64
65
66
# File 'lib/shrine/uploaded_file.rb', line 64

def mime_type
  ["mime_type"]
end

#open(**options) ⇒ Object

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

91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/shrine/uploaded_file.rb', line 91

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?Boolean

Returns whether the file has already been opened.

Returns:

  • (Boolean)

175
176
177
# File 'lib/shrine/uploaded_file.rb', line 175

def opened?
  !!@io
end

#original_filenameObject

The filename that was extracted from the uploaded file.


46
47
48
# File 'lib/shrine/uploaded_file.rb', line 46

def original_filename
  ["filename"]
end

#read(*args) ⇒ Object

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


152
153
154
# File 'lib/shrine/uploaded_file.rb', line 152

def read(*args)
  io.read(*args)
end

#replace(io, **options) ⇒ Object

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


191
192
193
# File 'lib/shrine/uploaded_file.rb', line 191

def replace(io, **options)
  uploader.upload(io, **options, location: id)
end

#rewindObject

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


164
165
166
# File 'lib/shrine/uploaded_file.rb', line 164

def rewind
  io.rewind
end

#shrine_classObject

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


247
248
249
# File 'lib/shrine/uploaded_file.rb', line 247

def shrine_class
  self.class.shrine_class
end

#sizeObject

The filesize of the uploaded file.


59
60
61
# File 'lib/shrine/uploaded_file.rb', line 59

def size
  (@io && @io.size) || (["size"] && Integer(["size"]))
end

#storageObject

Returns the storage that this file was uploaded to.


242
243
244
# File 'lib/shrine/uploaded_file.rb', line 242

def storage
  shrine_class.find_storage(storage_key)
end

#stream(destination, **options) ⇒ Object

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")

141
142
143
144
145
146
147
148
# File 'lib/shrine/uploaded_file.rb', line 141

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_ioObject

Returns an opened IO object for the uploaded file.


202
203
204
# File 'lib/shrine/uploaded_file.rb', line 202

def to_io
  io
end

#to_json(*args) ⇒ Object

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


208
209
210
# File 'lib/shrine/uploaded_file.rb', line 208

def to_json(*args)
  data.to_json(*args)
end

#uploaderObject

Returns an uploader object for the corresponding storage.


237
238
239
# File 'lib/shrine/uploaded_file.rb', line 237

def uploader
  shrine_class.new(storage_key)
end

#url(**options) ⇒ Object

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


180
181
182
# File 'lib/shrine/uploaded_file.rb', line 180

def url(**options)
  storage.url(id, **options)
end