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



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/attached/attachment.rb', line 73

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.



32
33
34
# File 'lib/attached/attachment.rb', line 32

def alias
  @alias
end

#aliasesObject (readonly)

Returns the value of attribute aliases.



31
32
33
# File 'lib/attached/attachment.rb', line 31

def aliases
  @aliases
end

#credentialsObject (readonly)

Returns the value of attribute credentials.



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

def credentials
  @credentials
end

#defaultObject (readonly)

Returns the value of attribute default.



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

def default
  @default
end

#errorsObject (readonly)

Returns the value of attribute errors.



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

def errors
  @errors
end

#fileObject

Returns the value of attribute file.



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

def file
  @file
end

#hostObject (readonly)

Returns the value of attribute host.



34
35
36
# File 'lib/attached/attachment.rb', line 34

def host
  @host
end

#instanceObject (readonly)

Returns the value of attribute instance.



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

def instance
  @instance
end

#mediumObject (readonly)

Returns the value of attribute medium.



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

def medium
  @medium
end

#missingObject (readonly)

Returns the value of attribute missing.



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

def missing
  @missing
end

#nameObject (readonly)

Returns the value of attribute name.



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

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)


264
265
266
# File 'lib/attached/attachment.rb', line 264

def path
  @path
end

#processorObject (readonly)

Returns the value of attribute processor.



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

def processor
  @processor
end

#processorsObject (readonly)

Returns the value of attribute processors.



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

def processors
  @processors
end

#purgeObject (readonly)

Returns the value of attribute purge.



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

def purge
  @purge
end

#queueObject (readonly)

Returns the value of attribute queue.



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

def queue
  @queue
end

#storageObject (readonly)

Returns the value of attribute storage.



33
34
35
# File 'lib/attached/attachment.rb', line 33

def storage
  @storage
end

#strategyObject (readonly)

Returns the value of attribute strategy.



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

def strategy
  @strategy
end

#stylesObject (readonly)

Returns the value of attribute styles.



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

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


43
44
45
46
47
48
49
50
51
52
# File 'lib/attached/attachment.rb', line 43

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(...)


158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/attached/attachment.rb', line 158

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)


136
137
138
# File 'lib/attached/attachment.rb', line 136

def attached?
  not identifier.blank?
end

#changed?Boolean

Check if an attachment has been modified.

Usage:

@object.avatar.changed?

Returns:

  • (Boolean)


114
115
116
# File 'lib/attached/attachment.rb', line 114

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

#destroyObject

Destroy an attachment.

Usage:

@object.avatar.destroy


225
226
227
228
229
230
231
232
233
234
235
# File 'lib/attached/attachment.rb', line 225

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:



305
306
307
308
309
310
311
# File 'lib/attached/attachment.rb', line 305

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:



359
360
361
# File 'lib/attached/attachment.rb', line 359

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

#file?Boolean

Check if an attachment is present.

Usage:

@object.avatar.file?

Returns:

  • (Boolean)


125
126
127
# File 'lib/attached/attachment.rb', line 125

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:



321
322
323
324
325
326
327
# File 'lib/attached/attachment.rb', line 321

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:



371
372
373
# File 'lib/attached/attachment.rb', line 371

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

#reprocess!Object

Access the original file .



378
379
380
381
382
# File 'lib/attached/attachment.rb', line 378

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

  process
end

#saveObject

Save an attachment.

Usage:

@object.avatar.save


204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/attached/attachment.rb', line 204

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:



282
283
284
# File 'lib/attached/attachment.rb', line 282

def size
  return instance_get(:size)
end

#size=(size) ⇒ Object

Set the size for an attachment.

Usage:



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

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

#statusObject

Access the status for an attachment.

Usage:



293
294
295
# File 'lib/attached/attachment.rb', line 293

def status
  instance_get(:status)
end

#status=(status) ⇒ Object

Set the status for an attachment.

Usage:



347
348
349
# File 'lib/attached/attachment.rb', line 347

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)


246
247
248
249
250
251
252
253
# File 'lib/attached/attachment.rb', line 246

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"


186
187
188
189
190
191
192
193
194
195
# File 'lib/attached/attachment.rb', line 186

def url=(url)
  extension = File.extname(url)

  file = Tempfile.new(["", extension])
  file.binmode

  file << open(url).read

  self.assign(file)
end