Module: Refile::ActiveRecord::Attachment

Includes:
Refile::Attachment
Defined in:
lib/refile/attachment/active_record.rb

Instance Method Summary collapse

Instance Method Details

#accepts_attachments_for(association_name, attachment: :file, append: false) ⇒ void

This method returns an undefined value.

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

The name of the generated accessors will be the name of the association and the name of the attachment in the associated model. So if a ‘Post` accepts attachments for `images`, and the attachment in the `Image` model is named `file`, then the accessors will be named `images_files`.

Examples:

in model

class Post
  has_many :images, dependent: :destroy
  accepts_attachments_for :images
end

in associated model

class Image
  attachment :image
end

in form

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

Parameters:

  • association_name (Symbol)

    Name of the association

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

    Name of the attachment in the associated model

  • append (Boolean) (defaults to: false)

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



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
# File 'lib/refile/attachment/active_record.rb', line 79

def accepts_attachments_for(association_name, attachment: :file, append: false)
  association = reflect_on_association(association_name)
  attachment_pluralized = attachment.to_s.pluralize
  name = "#{association_name}_#{attachment_pluralized}"
  collection_class = association && association.klass

  options = {
    collection_class: collection_class,
    name: name,
    attachment: attachment,
    append: append
  }

  mod = MultipleAttachments.new association_name, **options do
    define_method(:method_missing) do |method, *args|
      if method == attachment_pluralized.to_sym
        raise NoMethodError, "wrong association name #{method}, use like this #{name}"
      else
        super(method, *args)
      end
    end
  end

  include mod
end

#attachment(name, raise_errors: false, destroy: true, **options) ⇒ void

This method returns an undefined value.

Attachment method which hooks into ActiveRecord models

Parameters:

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

    Whether to remove the stored file if its model is destroyed

See Also:



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/refile/attachment/active_record.rb', line 11

def attachment(name, raise_errors: false, destroy: true, **options)
  super(name, raise_errors: raise_errors, **options)

  attacher = "#{name}_attacher"

  validate do
    if send(attacher).present?
      send(attacher).valid?
      errors = send(attacher).errors
      errors.each do |error|
        self.errors.add(name, *error)
      end
    end
  end

  define_method "#{name}=" do |value|
    send("#{name}_id_will_change!") if respond_to?("#{name}_id_will_change!")
    super(value)
  end

  define_method "remove_#{name}=" do |value|
    send("#{name}_id_will_change!")
    super(value)
  end

  define_method "remote_#{name}_url=" do |value|
    send("#{name}_id_will_change!")
    super(value)
  end

  before_save do
    send(attacher).store!
  end

  after_destroy do
    send(attacher).delete! if destroy
  end
end