Class | Paperclip::Attachment
In: | vendor/plugins/paperclip/lib/paperclip/attachment.rb
Parent: | Object

The Attachment class manages the files for a given attachment. It saves when the model saves, deletes when the model is destroyed, and processes the file upon assignment.

### Methods

assign content_type default_options dirty? errors file? instance_read instance_write interpolations new original_filename reprocess! save size to_s updated_at url valid?

### Attributes

convert_options | [R] |
default_style | [R] |
instance | [R] |
name | [R] |
queued_for_write | [R] |
styles | [R] |

### Public Class methods

default_options()

[Source]

        # File vendor/plugins/paperclip/lib/paperclip/attachment.rb, line 7
     7:     def self.default_options
     8:       @default_options ||= {
     9:         :url           => "/system/:attachment/:id/:style/:basename.:extension",
    10:         :path          => ":rails_root/public/system/:attachment/:id/:style/:basename.:extension",
    11:         :styles        => {},
    12:         :default_url   => "/:attachment/:style/missing.png",
    13:         :default_style => :original,
    14:         :validations   => {},
    15:         :storage       => :filesystem
    16:       }
    17:     end

interpolations()

A hash of procs that are run during the interpolation of a path or url. A variable of the format :name will be replaced with the return value of the proc named ":name". Each lambda takes the attachment and the current style as arguments. This hash can be added to with your own proc if necessary.

[Source]

         # File vendor/plugins/paperclip/lib/paperclip/attachment.rb, line 191
    191:     def self.interpolations
    192:       @interpolations ||= {
    193:         :rails_root   => lambda{|attachment,style| RAILS_ROOT },
    194:         :rails_env    => lambda{|attachment,style| RAILS_ENV },
    195:         :class        => lambda do |attachment,style|
    196:                            attachment.instance.class.name.underscore.pluralize
    197:                          end,
    198:         :basename     => lambda do |attachment,style|
    199:                            attachment.original_filename.gsub(/#{File.extname(attachment.original_filename)}$/, "")
    200:                          end,
    201:         :extension    => lambda do |attachment,style|
    202:                            ((style = attachment.styles[style]) && style[:format]) ||
    203:                            File.extname(attachment.original_filename).gsub(/^\.+/, "")
    204:                          end,
    205:         :id           => lambda{|attachment,style| attachment.instance.id },
    206:         :id_partition => lambda do |attachment, style|
    207:                            ("%09d" % attachment.instance.id).scan(/\d{3}/).join("/")
    208:                          end,
    209:         :attachment   => lambda{|attachment,style| attachment.name.to_s.downcase.pluralize },
    210:         :style        => lambda{|attachment,style| style || attachment.default_style },
    211:       }
    212:     end

new(name, instance, options = {})

Creates an Attachment object. `name` is the name of the attachment, `instance` is the ActiveRecord object instance it‘s attached to, and `options` is the same as the hash passed to `has_attached_file`.

[Source]

        # File vendor/plugins/paperclip/lib/paperclip/attachment.rb, line 24
    24:     def initialize name, instance, options = {}
    25:       @name              = name
    26:       @instance          = instance
    27:
    28:       options = self.class.default_options.merge(options)
    29:
    30:       @url               = options[:url]
    31:       @url               = @url.call(self) if @url.is_a?(Proc)
    32:       @path              = options[:path]
    33:       @path              = @path.call(self) if @path.is_a?(Proc)
    34:       @styles            = options[:styles]
    35:       @styles            = @styles.call(self) if @styles.is_a?(Proc)
    36:       @default_url       = options[:default_url]
    37:       @validations       = options[:validations]
    38:       @default_style     = options[:default_style]
    39:       @storage           = options[:storage]
    40:       @whiny             = options[:whiny_thumbnails]
    41:       @convert_options   = options[:convert_options] || {}
    42:       @processors        = options[:processors] || [:thumbnail]
    43:       @options           = options
    44:       @queued_for_delete = []
    45:       @queued_for_write  = {}
    46:       @errors            = {}
    47:       @validation_errors = nil
    48:       @dirty             = false
    49:
    50:       normalize_style_definition
    51:       initialize_storage
    52:
    53:       log("Paperclip attachment #{name} on #{instance.class} initialized.")
    54:     end

### Public Instance methods

assign(uploaded_file)

What gets called when you call instance.attachment = File. It clears errors, assigns attributes, processes the file, and runs validations. It also queues up the previous file for deletion, to be flushed away on save of its host. In addition to form uploads, you can also assign another Paperclip attachment:

      new_user.avatar = old_user.avatar

If the file that is assigned is not valid, the processing (i.e. thumbnailing, etc) will NOT be run.

[Source]

         # File vendor/plugins/paperclip/lib/paperclip/attachment.rb, line 64
     64:     def assign uploaded_file
     65:       %w(file_name).each do |field|
     66:         unless @instance.class.column_names.include?("#{name}_#{field}")
     67:           raise PaperclipError.new("#{@instance.class} model does not have required column '#{name}_#{field}'")
     68:         end
     69:       end
     70:
     71:       if uploaded_file.is_a?(Paperclip::Attachment)
     72:         uploaded_file = uploaded_file.to_file(:original)
     73:         close_uploaded_file = uploaded_file.respond_to?(:close)
     74:       end
     75:
     76:       return nil unless valid_assignment?(uploaded_file)
     77:       log("Assigning #{uploaded_file.inspect} to #{name}")
     78:
     79:       uploaded_file.binmode if uploaded_file.respond_to? :binmode
     80:       queue_existing_for_delete
     81:       @errors            = {}
     82:       @validation_errors = nil
     83:
     84:       return nil if uploaded_file.nil?
     85:
     86:       log("Writing attributes for #{name}")
     87:       @queued_for_write[:original]   = uploaded_file.to_tempfile
     88:       instance_write(:file_name,       uploaded_file.original_filename.strip.gsub(/[^\w\d\.\-]+/, '_'))
     89:       instance_write(:content_type,    uploaded_file.content_type.to_s.strip)
     90:       instance_write(:file_size,       uploaded_file.size.to_i)
     91:       instance_write(:updated_at,      Time.now)
     92:
     93:       @dirty = true
     94:
     95:       post_process if valid?
     96:
     97:       # Reset the file size if the original file was reprocessed.
     98:       instance_write(:file_size, @queued_for_write[:original].size.to_i)
     99:     ensure
    100:       uploaded_file.close if close_uploaded_file
    101:       validate
    102:     end

content_type()

Returns the content_type of the file as originally assigned, and lives in the <attachment>_content_type attribute of the model.

[Source]

         # File vendor/plugins/paperclip/lib/paperclip/attachment.rb, line 175
    175:     def content_type
    176:       instance_read(:content_type)
    177:     end

dirty?()

Returns true if there are changes that need to be saved.

[Source]

         # File vendor/plugins/paperclip/lib/paperclip/attachment.rb, line 141
    141:     def dirty?
    142:       @dirty
    143:     end

errors()

Returns an array containing the errors on this attachment.

[Source]

         # File vendor/plugins/paperclip/lib/paperclip/attachment.rb, line 136
    136:     def errors
    137:       @errors
    138:     end

file?()

Returns true if a file has been assigned.

[Source]

         # File vendor/plugins/paperclip/lib/paperclip/attachment.rb, line 237
    237:     def file?
    238:       !original_filename.blank?
    239:     end

instance_read(attr)

Reads the attachment-specific attribute on the instance. See instance_write for more details.

[Source]

         # File vendor/plugins/paperclip/lib/paperclip/attachment.rb, line 253
    253:     def instance_read(attr)
    254:       getter = "#{name}_#{attr}""#{name}_#{attr}"
    255:       responds = instance.respond_to?(getter)
    256:       cached = self.instance_variable_get("@_#{getter}")
    257:       return cached if cached
    258:       instance.send(getter) if responds || attr.to_s == "file_name"
    259:     end

instance_write(attr, value)

Writes the attachment-specific attribute on the instance. For example, instance_write(:file_name, "me.jpg") will write "me.jpg" to the instance‘s "avatar_file_name" field (assuming the attachment is called avatar).

[Source]

         # File vendor/plugins/paperclip/lib/paperclip/attachment.rb, line 244
    244:     def instance_write(attr, value)
    245:       setter = "#{name}_#{attr}=""#{name}_#{attr}="
    246:       responds = instance.respond_to?(setter)
    247:       self.instance_variable_set("@_#{setter.to_s.chop}", value)
    248:       instance.send(setter, value) if responds || attr.to_s == "file_name"
    249:     end

original_filename()

Returns the name of the file as originally assigned, and lives in the <attachment>_file_name attribute of the model.

[Source]

         # File vendor/plugins/paperclip/lib/paperclip/attachment.rb, line 163
    163:     def original_filename
    164:       instance_read(:file_name)
    165:     end

reprocess!()

This method really shouldn‘t be called that often. It‘s expected use is in the paperclip:refresh rake task and that‘s it. It will regenerate all thumbnails forcefully, by reobtaining the original file and going through the post-process again.

[Source]

         # File vendor/plugins/paperclip/lib/paperclip/attachment.rb, line 218
    218:     def reprocess!
    219:       new_original = Tempfile.new("paperclip-reprocess")
    220:       new_original.binmode
    221:       if old_original = to_file(:original)
    222:         new_original.write( old_original.read )
    223:         new_original.rewind
    224:
    225:         @queued_for_write = { :original => new_original }
    226:         post_process
    227:
    228:         old_original.close if old_original.respond_to?(:close)
    229:
    230:         save
    231:       else
    232:         true
    233:       end
    234:     end

save()

Saves the file, if there are no errors. If there are, it flushes them to the instance‘s errors and returns false, cancelling the save.

[Source]

         # File vendor/plugins/paperclip/lib/paperclip/attachment.rb, line 147
    147:     def save
    148:       if valid?
    149:         log("Saving files for #{name}")
    150:         flush_deletes
    151:         flush_writes
    152:         @dirty = false
    153:         true
    154:       else
    155:         log("Errors on #{name}. Not saving.")
    156:         flush_errors
    157:         false
    158:       end
    159:     end

size()

Returns the size of the file as originally assigned, and lives in the <attachment>_file_size attribute of the model.

[Source]

         # File vendor/plugins/paperclip/lib/paperclip/attachment.rb, line 169
    169:     def size
    170:       instance_read(:file_size) || (@queued_for_write[:original] && @queued_for_write[:original].size)
    171:     end

to_s(style = nil)

Alias to `url`

[Source]

         # File vendor/plugins/paperclip/lib/paperclip/attachment.rb, line 125
    125:     def to_s style = nil
    126:       url(style)
    127:     end

updated_at()

Returns the last modified time of the file as originally assigned, and lives in the <attachment>_updated_at attribute of the model.

[Source]

         # File vendor/plugins/paperclip/lib/paperclip/attachment.rb, line 181
    181:     def updated_at
    182:       time = instance_read(:updated_at)
    183:       time && time.to_i
    184:     end

url(style = default_style, include_updated_timestamp = true)

Returns the public URL of the attachment, with a given style. Note that this does not necessarily need to point to a file that your web server can access and can point to an action in your app, if you need fine grained security. This is not recommended if you don‘t need the security, however, for performance reasons. set include_updated_timestamp to false if you want to stop the attachment update time appended to the url

[Source]

         # File vendor/plugins/paperclip/lib/paperclip/attachment.rb, line 111
    111:     def url style = default_style, include_updated_timestamp = true
    112:       url = original_filename.nil? ? interpolate(@default_url, style) : interpolate(@url, style)
    113:       include_updated_timestamp && updated_at ? [url, updated_at].compact.join(url.include?("?") ? "&" : "?") : url
    114:     end

valid?()

Returns true if there are no errors on this attachment.

[Source]

         # File vendor/plugins/paperclip/lib/paperclip/attachment.rb, line 130
    130:     def valid?
    131:       validate
    132:       errors.empty?
    133:     end

[Validate]