module Refile::ActiveRecord::Attachment

Public Instance Methods

accepts_attachments_for(association_name, attachment: :file, append: false) click to toggle source

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`.

@example in model

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

@example in associated model

class Image
  attachment :image
end

@example in form

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

@param [Symbol] association_name Name of the association @param [Symbol] attachment Name of the attachment in the associated model @param [Boolean] append If true, new files are appended instead of replacing the entire list of associated models. @return [void]

# 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) click to toggle source

Attachment method which hooks into ActiveRecord models

@param [true, false] destroy Whether to remove the stored file if its model is destroyed @return [void] @see Refile::Attachment#attachment

Calls superclass method Refile::Attachment#attachment
# 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