Class: Attached::Attachment

Inherits:
Object
  • Object
show all
Defined in:
lib/attached/attachment.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, instance, options = {}) ⇒ Attachment

Initialize a new attachment by providing a name and the instance the attachment is associated with.

Parameters:

  • name - The name for the attachment such as ‘avatar’ or ‘photo’

  • instance - The instance the attachment is attached to

Options:

  • :path - The location where the attachment is stored

  • :styles - A hash containing optional parameters including extension and identifier

  • :credentials - A file, hash, or path used to authenticate with the specified storage medium

  • :medium - A symbol or subclass of ‘Attached::Storage::Base’ to be used

  • :processor - A symbol or subclass of ‘Attached::Processor::Base’ to be used

  • :alias - A string representing a fully qualified host alias

  • :processors - An array of processors

  • :aliases - An array of aliases



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/attached/attachment.rb', line 66

def initialize(name, instance, options = {})
  options = self.class.options.clone.merge(options)

  options[:styles]     ||= {}
  options[:aliases]    ||= []
  options[:processors] ||= []

  @name        = name
  @instance    = instance
  @queue       = {}
  @purge       = []
  @errors      = []
  @path        = options[:path]
  @missing     = options[:missing]
  @styles      = options[:styles]
  @default     = options[:default]
  @strategy    = options[:strategy]
  @medium      = options[:medium]
  @credentials = options[:credentials]
  @processors  = options[:processors]
  @processor   = options[:processor]
  @aliases     = options[:aliases]
  @alias       = options[:alias]
  @aliases     = self.aliases << self.alias if self.alias
  @processors  = self.processors << self.processor if self.processor
  @storage     = Attached::Storage.storage(self.medium, self.credentials)
  @host        = self.storage.host
end

Instance Attribute Details

#aliasObject (readonly)

Returns the value of attribute alias.



27
28
29
# File 'lib/attached/attachment.rb', line 27

def alias
  @alias
end

#aliasesObject (readonly)

Returns the value of attribute aliases.



26
27
28
# File 'lib/attached/attachment.rb', line 26

def aliases
  @aliases
end

#credentialsObject (readonly)

Returns the value of attribute credentials.



23
24
25
# File 'lib/attached/attachment.rb', line 23

def credentials
  @credentials
end

#defaultObject (readonly)

Returns the value of attribute default.



20
21
22
# File 'lib/attached/attachment.rb', line 20

def default
  @default
end

#errorsObject (readonly)

Returns the value of attribute errors.



16
17
18
# File 'lib/attached/attachment.rb', line 16

def errors
  @errors
end

#fileObject

Returns the value of attribute file.



11
12
13
# File 'lib/attached/attachment.rb', line 11

def file
  @file
end

#hostObject (readonly)

Returns the value of attribute host.



29
30
31
# File 'lib/attached/attachment.rb', line 29

def host
  @host
end

#instanceObject (readonly)

Returns the value of attribute instance.



13
14
15
# File 'lib/attached/attachment.rb', line 13

def instance
  @instance
end

#mediumObject (readonly)

Returns the value of attribute medium.



22
23
24
# File 'lib/attached/attachment.rb', line 22

def medium
  @medium
end

#missingObject (readonly)

Returns the value of attribute missing.



18
19
20
# File 'lib/attached/attachment.rb', line 18

def missing
  @missing
end

#nameObject (readonly)

Returns the value of attribute name.



12
13
14
# File 'lib/attached/attachment.rb', line 12

def name
  @name
end

#path(style = self.default) ⇒ Object (readonly)

Access the path for an attachment.

Usage:

@object.avatar.url
@object.avatar.url(:small)
@object.avatar.url(:large)


233
234
235
# File 'lib/attached/attachment.rb', line 233

def path
  @path
end

#processorObject (readonly)

Returns the value of attribute processor.



25
26
27
# File 'lib/attached/attachment.rb', line 25

def processor
  @processor
end

#processorsObject (readonly)

Returns the value of attribute processors.



24
25
26
# File 'lib/attached/attachment.rb', line 24

def processors
  @processors
end

#purgeObject (readonly)

Returns the value of attribute purge.



15
16
17
# File 'lib/attached/attachment.rb', line 15

def purge
  @purge
end

#queueObject (readonly)

Returns the value of attribute queue.



14
15
16
# File 'lib/attached/attachment.rb', line 14

def queue
  @queue
end

#storageObject (readonly)

Returns the value of attribute storage.



28
29
30
# File 'lib/attached/attachment.rb', line 28

def storage
  @storage
end

#strategyObject (readonly)

Returns the value of attribute strategy.



21
22
23
# File 'lib/attached/attachment.rb', line 21

def strategy
  @strategy
end

#stylesObject (readonly)

Returns the value of attribute styles.



19
20
21
# File 'lib/attached/attachment.rb', line 19

def styles
  @styles
end

Class Method Details

.optionsObject

A default set of options that can be extended to customize the path, storage or credentials.

Usage:

Attached::Attachment.options = { storage: :fs, path: ":name/:style/:identifier:extension" }


37
38
39
40
41
42
43
44
45
46
# File 'lib/attached/attachment.rb', line 37

def self.options
  @options ||= {
    path: ":name/:style/:identifier:extension",
    missing: ":name/:style/missing:extension",
    default: :original,
    medium: :local,
    credentials: {},
    metadata: { 'Cache-Control' => 'max-age=3153600' }
  }
end

Instance Method Details

#assign(file, identifier = Identifier.generate) ⇒ Object

Assign an attachment to a file.

Usage:

@object.avatar.assign(...)


141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/attached/attachment.rb', line 141

def assign(file, identifier = Identifier.generate)
  self.file = file

  if file
    extension ||= file.extension if file.respond_to? :extension
    extension ||= File.extname(file.original_filename) if file.respond_to? :original_filename
    extension ||= File.extname(file.path) if file.respond_to? :path
    size ||= file.size if file.respond_to? :size
    size ||= File.size(file.path) if file.respond_to? :path
  end

  @purge = [self.path, *self.styles.map { |style, options| self.path(style) }] if attached?

  self.size       = file ? size       : nil
  self.extension  = file ? extension  : nil
  self.identifier = file ? identifier : nil

  process if file
end

#attached?Boolean

Check if an attachment is present.

Usage:

@object.avatar.attached?

Returns:

  • (Boolean)


121
122
123
# File 'lib/attached/attachment.rb', line 121

def attached?
  not identifier.blank?
end

#changed?Boolean

Check if an attachment has been modified.

Usage:

@object.avatar.changed?

Returns:

  • (Boolean)


101
102
103
# File 'lib/attached/attachment.rb', line 101

def changed?
  instance.changed.include? "#{name}_identifier"
end

#destroyObject

Destroy an attachment.

Usage:

@object.avatar.destroy


199
200
201
202
203
204
205
206
207
208
# File 'lib/attached/attachment.rb', line 199

def destroy
  if attached?
    self.storage.destroy(self.path)
    self.styles.each do |style, options|
      self.storage.destroy(self.path(style))
    end
  end
  @purge = []
  @queue = {}
end

#extension(style = nil) ⇒ Object

Access the extension for an attachment. It will first check the styles to see if one is specified before checking the instance.

Usage:



269
270
271
272
273
274
275
# File 'lib/attached/attachment.rb', line 269

def extension(style = nil)
  style and
  self.styles and
  self.styles[style] and
  self.styles[style][:extension] or
  instance_get(:extension)
end

#extension=(extension) ⇒ Object

Set the extension for an attachment. It will act independently of the defined style.

Usage:



319
320
321
# File 'lib/attached/attachment.rb', line 319

def extension=(extension)
  instance_set(:extension, extension)
end

#file?Boolean

Check if an attachment is present.

Usage:

@object.avatar.file?

Returns:

  • (Boolean)


111
112
113
# File 'lib/attached/attachment.rb', line 111

def file?
  not identifier.blank?
end

#identifier(style = nil) ⇒ Object

Access the identifier for an attachment. It will first check the styles to see if one is specified before checking the instance.

Usage:



284
285
286
287
288
289
290
# File 'lib/attached/attachment.rb', line 284

def identifier(style = nil)
  style and
  self.styles and
  self.styles[style] and
  self.styles[style][:identifier] or
  instance_get(:identifier)
end

#identifier=(identifier) ⇒ Object

Set the identifier for an attachment. It will act independently of the defined style.

Usage:



330
331
332
# File 'lib/attached/attachment.rb', line 330

def identifier=(identifier)
  instance_set(:identifier, identifier)
end

#reprocess!Object

Access the original file .



336
337
338
339
# File 'lib/attached/attachment.rb', line 336

def reprocess!
  self.file = self.storage.retrieve(self.path)
  process
end

#saveObject

Save an attachment.

Usage:

@object.avatar.save


181
182
183
184
185
186
187
188
189
190
191
# File 'lib/attached/attachment.rb', line 181

def save
  self.queue.each do |style, file|
    path = self.path(style)
    self.storage.save(file, path) if file and path
  end
  self.purge.each do |path|
    self.storage.destroy(path)
  end
  @purge = []
  @queue = {}
end

#sizeObject

Access the size for an attachment.

Usage:



248
249
250
# File 'lib/attached/attachment.rb', line 248

def size
  return instance_get(:size)
end

#size=(size) ⇒ Object

Set the size for an attachment.

Usage:



298
299
300
# File 'lib/attached/attachment.rb', line 298

def size=(size)
  instance_set(:size, size)
end

#statusObject

Access the status for an attachment.

Usage:



258
259
260
# File 'lib/attached/attachment.rb', line 258

def status
  instance_get(:status)
end

#status=(status) ⇒ Object

Set the status for an attachment.

Usage:



308
309
310
# File 'lib/attached/attachment.rb', line 308

def status=(status)
  instance_set(:size, status)
end

#url(style = self.default) ⇒ Object

Acesss the URL for an attachment.

Usage:

@object.avatar.url
@object.avatar.url(:small)
@object.avatar.url(:large)


218
219
220
221
222
223
# File 'lib/attached/attachment.rb', line 218

def url(style = self.default)
  path = self.path(style)
  host = self.host
  host = self.aliases[path.hash % self.aliases.count] unless self.aliases.empty?
  return "#{host}#{path}"
end

#url=(url) ⇒ Object

Assign an attachment to a file.

Usage:

@object.avatar.url = "https://.../file"


167
168
169
170
171
172
173
# File 'lib/attached/attachment.rb', line 167

def url=(url)
  extension = File.extname(url)
  file = Tempfile.new(["", extension])
  file.binmode
  file << open(url).read
  self.assign(file)
end