module Shrine::Attacher::InstanceMethods

  1. lib/shrine/attacher.rb

Attributes

context [R]

Returns options that are automatically forwarded to the uploader. Can be modified with additional data.

file [R]

Returns the attached uploaded file.

Public Class methods

new(file: nil, cache: :cache, store: :store)

Initializes the attached file, temporary and permanent storage.

[show source]
   # File lib/shrine/attacher.rb
41 def initialize(file: nil, cache: :cache, store: :store)
42   @file     = file
43   @cache    = cache
44   @store    = store
45   @context  = {}
46   @previous = nil
47 end

Public Instance methods

assign(value, **options)

Calls attach_cached, but skips if value is an empty string (this is useful when the uploaded file comes from form fields). Forwards any additional options to attach_cached.

attacher.assign(File.open(...))
attacher.assign(File.open(...), metadata: { "foo" => "bar" })
attacher.assign('{"id":"...","storage":"cache","metadata":{...}}')
attacher.assign({ "id" => "...", "storage" => "cache", "metadata" => {} })

# ignores the assignment when a blank string is given
attacher.assign("")
[show source]
   # File lib/shrine/attacher.rb
70 def assign(value, **options)
71   return if value == "" # skip empty hidden field
72 
73   if value.is_a?(Hash) || value.is_a?(String)
74     return if uploaded_file(value) == file # skip assignment for current file
75   end
76 
77   attach_cached(value, **options)
78 end
attach(io, storage: store_key, **options)

Uploads given IO object and changes the uploaded file.

# uploads the file to permanent storage
attacher.attach(io)

# uploads the file to specified storage
attacher.attach(io, storage: :other_store)

# forwards additional options to the uploader
attacher.attach(io, upload_options: { acl: "public-read" }, metadata: { "foo" => "bar" })

# removes the attachment
attacher.attach(nil)
[show source]
    # File lib/shrine/attacher.rb
116 def attach(io, storage: store_key, **options)
117   file = upload(io, storage, **options) if io
118 
119   change(file)
120 end
attach_cached(value, **options)

Sets an existing cached file, or uploads an IO object to temporary storage and sets it via attach. Forwards any additional options to

attach.

# upload file to temporary storage and set the uploaded file.
attacher.attach_cached(File.open(...))

# foward additional options to the uploader
attacher.attach_cached(File.open(...), metadata: { "foo" => "bar" })

# sets an existing cached file from JSON data
attacher.attach_cached('{"id":"...","storage":"cache","metadata":{...}}')

# sets an existing cached file from Hash data
attacher.attach_cached({ "id" => "...", "storage" => "cache", "metadata" => {} })
[show source]
    # File lib/shrine/attacher.rb
 95 def attach_cached(value, **options)
 96   if value.is_a?(String) || value.is_a?(Hash)
 97     change(cached(value, **options))
 98   else
 99     attach(value, storage: cache_key, action: :cache, **options)
100   end
101 end
attached?()

Returns whether a file is attached.

attacher.attach(io)
attacher.attached? #=> true

attacher.attach(nil)
attacher.attached? #=> false
[show source]
    # File lib/shrine/attacher.rb
272 def attached?
273   !!file
274 end
cache()

Returns the uploader that is used for the temporary storage.

[show source]
   # File lib/shrine/attacher.rb
55 def cache; shrine_class.new(cache_key); end
cache_key()

Returns the temporary storage identifier.

[show source]
   # File lib/shrine/attacher.rb
50 def cache_key; @cache.to_sym; end
cached?(file = self.file)

Returns whether the file is uploaded to temporary storage.

attacher.cached?       # checks current file
attacher.cached?(file) # checks given file
[show source]
    # File lib/shrine/attacher.rb
280 def cached?(file = self.file)
281   uploaded?(file, cache_key)
282 end
change(file)

Sets the uploaded file with dirty tracking, and runs validations.

attacher.change(uploaded_file)
attacher.file #=> #<Shrine::UploadedFile>
attacher.changed? #=> true
[show source]
    # File lib/shrine/attacher.rb
219 def change(file)
220   @previous = dup if change?(file)
221   set(file)
222 end
changed?()

Returns whether the attachment has changed.

attacher.changed? #=> false
attacher.attach(file)
attacher.changed? #=> true
[show source]
    # File lib/shrine/attacher.rb
261 def changed?
262   !!@previous
263 end
data()

Generates serializable data for the attachment.

attacher.data #=> { "id" => "...", "storage" => "...", "metadata": { ... } }
[show source]
    # File lib/shrine/attacher.rb
295 def data
296   file&.data
297 end
destroy()

Destroys the attachment.

attacher.file.exists? #=> true
attacher.destroy
attacher.file.exists? #=> false
[show source]
    # File lib/shrine/attacher.rb
210 def destroy
211   file&.delete
212 end
destroy_attached()

Destroys the attached file if it exists and is uploaded to permanent storage.

attacher.file.exists? #=> true
attacher.destroy_attached
attacher.file.exists? #=> false
[show source]
    # File lib/shrine/attacher.rb
201 def destroy_attached
202   destroy if destroy?
203 end
destroy_previous()

If a new file was attached, deletes previously attached file if any.

previous_file = attacher.file
attacher.attach(file)
attacher.destroy_previous
previous_file.exists? #=> false
[show source]
    # File lib/shrine/attacher.rb
191 def destroy_previous
192   @previous.destroy_attached if changed?
193 end
file!()

Returns attached file or raises an exception if no file is attached.

[show source]
    # File lib/shrine/attacher.rb
321 def file!
322   file or fail Error, "no file is attached"
323 end
file=(file)

Saves the given uploaded file to an instance variable.

attacher.file = uploaded_file
attacher.file #=> #<Shrine::UploadedFile>
[show source]
    # File lib/shrine/attacher.rb
312 def file=(file)
313   unless file.is_a?(Shrine::UploadedFile) || file.nil?
314     fail ArgumentError, "expected file to be a Shrine::UploadedFile or nil, got #{file.inspect}"
315   end
316 
317   @file = file
318 end
finalize()

Deletes any previous file and promotes newly attached cached file. It also clears any dirty tracking.

# promoting cached file
attacher.assign(io)
attacher.cached? #=> true
attacher.finalize
attacher.stored?

# deleting previous file
previous_file = attacher.file
previous_file.exists? #=> true
attacher.assign(io)
attacher.finalize
previous_file.exists? #=> false

# clearing dirty tracking
attacher.assign(io)
attacher.changed? #=> true
attacher.finalize
attacher.changed? #=> false
[show source]
    # File lib/shrine/attacher.rb
143 def finalize
144   destroy_previous
145   promote_cached
146   @previous = nil
147 end
get()

Returns the attached file.

# when a file is attached
attacher.get #=> #<Shrine::UploadedFile>

# when no file is attached
attacher.get #=> nil
[show source]
    # File lib/shrine/attacher.rb
240 def get
241   file
242 end
load_data(data)

Loads the uploaded file from data generated by Attacher#data.

attacher.file #=> nil
attacher.load_data({ "id" => "...", "storage" => "...", "metadata" => { ... } })
attacher.file #=> #<Shrine::UploadedFile>
[show source]
    # File lib/shrine/attacher.rb
304 def load_data(data)
305   @file = data && uploaded_file(data)
306 end
promote(storage: store_key, **options)

Uploads current file to permanent storage and sets the stored file.

attacher.cached? #=> true
attacher.promote
attacher.stored? #=> true
[show source]
    # File lib/shrine/attacher.rb
170 def promote(storage: store_key, **options)
171   set upload(file, storage, action: :store, **options)
172 end
promote_cached(**options)

If a new cached file has been attached, uploads it to permanent storage. Any additional options are forwarded to promote.

attacher.assign(io)
attacher.cached? #=> true
attacher.promote_cached
attacher.stored? #=> true
[show source]
    # File lib/shrine/attacher.rb
161 def promote_cached(**options)
162   promote(**options) if promote?
163 end
save()

Plugins can override this if they want something to be done in a “before save” callback.

[show source]
    # File lib/shrine/attacher.rb
151 def save
152 end
set(file)

Sets the uploaded file.

attacher.set(uploaded_file)
attacher.file #=> #<Shrine::UploadedFile>
attacher.changed? #=> false
[show source]
    # File lib/shrine/attacher.rb
229 def set(file)
230   self.file = file
231 end
shrine_class()

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

[show source]
    # File lib/shrine/attacher.rb
338 def shrine_class
339   self.class.shrine_class
340 end
store()

Returns the uploader that is used for the permanent storage.

[show source]
   # File lib/shrine/attacher.rb
57 def store; shrine_class.new(store_key); end
store_key()

Returns the permanent storage identifier.

[show source]
   # File lib/shrine/attacher.rb
52 def store_key; @store.to_sym; end
stored?(file = self.file)

Returns whether the file is uploaded to permanent storage.

attacher.stored?       # checks current file
attacher.stored?(file) # checks given file
[show source]
    # File lib/shrine/attacher.rb
288 def stored?(file = self.file)
289   uploaded?(file, store_key)
290 end
upload(io, storage = store_key, **options)

Delegates to Shrine.upload, passing the context.

# upload file to specified storage
attacher.upload(io, :store) #=> #<Shrine::UploadedFile>

# pass additional options for the uploader
attacher.upload(io, :store, metadata: { "foo" => "bar" })
[show source]
    # File lib/shrine/attacher.rb
181 def upload(io, storage = store_key, **options)
182   shrine_class.upload(io, storage, **context, **options)
183 end
uploaded_file(value)

Converts JSON or Hash data into a Shrine::UploadedFile object.

attacher.uploaded_file('{"id":"...","storage":"...","metadata":{...}}')
#=> #<Shrine::UploadedFile ...>

attacher.uploaded_file({ "id" => "...", "storage" => "...", "metadata" => {} })
#=> #<Shrine::UploadedFile ...>
[show source]
    # File lib/shrine/attacher.rb
332 def uploaded_file(value)
333   shrine_class.uploaded_file(value)
334 end
url(**options)

If a file is attached, returns the uploaded file URL, otherwise returns nil. Any options are forwarded to the storage.

attacher.file = file
attacher.url #=> "https://..."

attacher.file = nil
attacher.url #=> nil
[show source]
    # File lib/shrine/attacher.rb
252 def url(**options)
253   file&.url(**options)
254 end