Class: Compony::ModelFields::Attachment

Inherits:
Base
  • Object
show all
Defined in:
lib/compony/model_fields/attachment.rb

Overview

Model field type representing an ActiveStorage attachment.

Instance Attribute Summary

Attributes inherited from Base

#extra_attrs, #model_class, #name, #schema_key

Instance Method Summary collapse

Methods inherited from Base

#association?, #label, #multi?, #ransack_filter_input, #ransack_filter_name, #schema_line, #simpleform_input_hidden, #transform_and_join

Constructor Details

#initializeAttachment

Returns a new instance of Attachment.



6
7
8
9
# File 'lib/compony/model_fields/attachment.rb', line 6

def initialize(...)
  super
  resolve_attachment!
end

Instance Method Details

#resolve_attachment!Object (protected)

Uses Rails method to figure out arity and store it. This can be auto-inferred without accessing the database.



58
59
60
61
# File 'lib/compony/model_fields/attachment.rb', line 58

def resolve_attachment!
  attachment_info = model_class.reflect_on_attachment(name)
  @multi = attachment_info.is_a?(ActiveStorage::Reflection::HasManyAttachedReflection)
end

#simpleform_input(form, _component, name: nil, accept: nil, **input_opts) ⇒ Object



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
49
50
51
52
# File 'lib/compony/model_fields/attachment.rb', line 24

def simpleform_input(form, _component, name: nil, accept: nil, **input_opts)
  name ||= @name
  input_opts.deep_merge!(input_html: { accept: }) if accept
  if @multi
    if form.object.new_record?
      # signed id is only calculated when the attachment is actually attached, cannot provide buttons for new records
      return form.input(name, **input_opts.deep_merge(input_html: { multiple: :multiple }))
    else
      helpers = ActionController::Base.helpers
      return helpers.capture do
        helpers.concat form.label(name)
        # List currently present attachments along with a remove button (done in JS)
        helpers.div class: 'compony-attachments-item-wrapper' do
          form.object.send(name).each do |attachment|
            helpers.div class: 'compony-attachments-item' do
              helpers.concat helpers.hidden_field_tag("#{form.object.model_name.singular}[#{name}][]", attachment.signed_id)
              helpers.span attachment.filename, class: 'compony-attachments-filename'
              helpers.span ' ', class: 'compony-attachments-spacer'
              helpers.concat helpers.link_to(I18n.t('compony.model_fields.attachment.remove'), '#',
                                             onclick: "event.preventDefault(); this.closest('div').remove();")
            end
          end
        end
        helpers.concat form.input(name, **input_opts.deep_merge(input_html: { multiple: :multiple }, label: false, class: 'compony-attachments-input'))
      end
    end
  end
  return form.input(name, **input_opts)
end

#value_for(data, controller: nil, **_) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/compony/model_fields/attachment.rb', line 11

def value_for(data, controller: nil, **_)
  return transform_and_join(data.send(@name), controller:) do |el|
    fail('Must pass controller to generate the link to the attachment.') unless controller
    if @multi
      return nil if el.none?
      return controller.helpers.safe_join(el.map { |item| controller.helpers.link_to(item.filename, controller.helpers.rails_blob_path(item)) }, ', ')
    else
      return nil unless el.attached?
      return controller.helpers.link_to(el.filename, controller.helpers.rails_blob_path(el))
    end
  end
end