Module: Refile::Attachment

Included in:
Refile::ActiveRecord::Attachment
Defined in:
lib/refile/attachment.rb,
lib/refile/attachment/multiple_attachments.rb

Instance Method Summary collapse

Instance Method Details

#accepts_attachments_for(collection_name, collection_class:, accessor_prefix:, attachment: :file, append: false)

This method returns an undefined value.

Macro which generates accessors in pure Ruby classes for assigning multiple attachments at once. This is primarily useful together with multiple file uploads. There is also an Active Record version of this macro.

The name of the generated accessors will be the name of the association (represented by an attribute accessor) and the name of the attachment in the associated class. So if a Post accepts attachments for images, and the attachment in the Image class is named file, then the accessors will be named images_files.

Examples:

in associated class

class Document
  extend Refile::Attachment
  attr_accessor :file_id

  attachment :file

  def initialize(attributes = {})
    self.file = attributes[:file]
  end
end

in class

class Post
  extend Refile::Attachment
  include ActiveModel::Model

  attr_accessor :documents

  accepts_attachments_for :documents, accessor_prefix: 'documents_files', collection_class: Document

  def initialize(attributes = {})
    @documents = attributes[:documents] || []
  end
end

in form

<%= form_for @post do |form| %>
  <%= form.attachment_field :documents_files, multiple: true %>
<% end %>

Parameters:

  • collection_name (Symbol)

    Name of the association

  • collection_class (Class)

    Associated class

  • accessor_prefix (String)

    Name of the generated accessors

  • attachment (Symbol) (defaults to: :file)

    Name of the attachment in the associated class

  • append (Boolean) (defaults to: false)

    If true, new files are appended instead of replacing the entire list of associated classes.


156
157
158
159
160
161
162
163
164
# File 'lib/refile/attachment.rb', line 156

def accepts_attachments_for(collection_name, collection_class:, accessor_prefix:, attachment: :file, append: false)
  include MultipleAttachments.new(
    collection_name,
    collection_class: collection_class,
    name: accessor_prefix,
    attachment: attachment,
    append: append
  )
end

#attachment(name, cache: :cache, store: :store, raise_errors: true, type: nil, extension: nil, content_type: nil)

This method returns an undefined value.

Macro which generates accessors for the given column which make it possible to upload and retrieve previously uploaded files through the generated accessors.

The raise_errors option controls whether assigning an invalid file should immediately raise an error, or save the error and defer handling it until later.

Given a record with an attachment named image, the following methods will be added:

  • image
  • image=
  • remove_image
  • remove_image=
  • remote_image_url
  • remote_image_url=
  • image_url
  • image_presigned_url

Examples:

class User
  extend Refile::Attachment

  attachment :image
  attr_accessor :image_id
end

Parameters:

  • name (String)

    Name of the column which accessor are generated for

  • cache (#to_s) (defaults to: :cache)

    Name of a backend in Refile.backends to use as transient cache

  • store (#to_s) (defaults to: :store)

    Name of a backend in Refile.backends to use as permanent store

  • raise_errors (true, false) (defaults to: true)

    Whether to raise errors in case an invalid file is assigned

  • type (Symbol, nil) (defaults to: nil)

    The type of file that can be uploaded, see Refile.types

  • extension (String, Array<String>, nil) (defaults to: nil)

    Limit the uploaded file to the given extension or list of extensions

  • content_type (String, Array<String>, nil) (defaults to: nil)

    Limit the uploaded file to the given content type or list of content types


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/refile/attachment.rb', line 39

def attachment(name, cache: :cache, store: :store, raise_errors: true, type: nil, extension: nil, content_type: nil)
  definition = AttachmentDefinition.new(name,
    cache: cache,
    store: store,
    raise_errors: raise_errors,
    type: type,
    extension: extension,
    content_type: content_type
  )

  define_singleton_method :"#{name}_attachment_definition" do
    definition
  end

  mod = Module.new do
    attacher = :"#{name}_attacher"

    define_method :"#{name}_attachment_definition" do
      definition
    end

    define_method attacher do
      ivar = :"@#{attacher}"
      instance_variable_get(ivar) or instance_variable_set(ivar, Attacher.new(definition, self))
    end

    define_method "#{name}=" do |value|
      send(attacher).set(value)
    end

    define_method name do
      send(attacher).get
    end

    define_method "remove_#{name}=" do |remove|
      send(attacher).remove = remove
    end

    define_method "remove_#{name}" do
      send(attacher).remove
    end

    define_method "remote_#{name}_url=" do |url|
      send(attacher).download(url)
    end

    define_method "remote_#{name}_url" do
    end

    define_method "#{name}_url" do |*args|
      Refile.attachment_url(self, name, *args)
    end

    define_method "presigned_#{name}_url" do |expires_in = 900|
      attachment = send(attacher)
      attachment.store.object(attachment.id).presigned_url(:get, expires_in: expires_in) unless attachment.id.nil?
    end

    define_method "#{name}_data" do
      send(attacher).data
    end

    define_singleton_method("to_s")    { "Refile::Attachment(#{name})" }
    define_singleton_method("inspect") { "Refile::Attachment(#{name})" }
  end

  include mod
end