chore(attachment): input name attribute follows form object name for nested attributes

This commit is contained in:
Colin Darie 2022-11-28 11:38:28 +01:00
parent 6e8302101f
commit c98021e58a
7 changed files with 28 additions and 8 deletions

View file

@ -30,6 +30,10 @@ class Attachment::EditComponent < ApplicationComponent
fail ArgumentError, "You must pass an `attachment` kwarg when not using as single attachment like in #{attached_file.name}. Set it to nil for a new attachment."
end
# When parent form has nested attributes, pass the form builder object_name
# to correctly infer the input attribute name.
@form_object_name = kwargs.delete(:form_object_name)
verify_initialization!(kwargs)
end
@ -81,7 +85,7 @@ class Attachment::EditComponent < ApplicationComponent
end
def field_name
helpers.field_name(ActiveModel::Naming.param_key(@attached_file.record), attribute_name)
helpers.field_name(@form_object_name || ActiveModel::Naming.param_key(@attached_file.record), attribute_name)
end
def attribute_name
@ -136,7 +140,7 @@ class Attachment::EditComponent < ApplicationComponent
return champ.input_id
end
helpers.field_id(@attached_file.record, attribute_name)
helpers.field_id(@form_object_name || @attached_file.record, attribute_name)
end
def auto_attach_url

View file

@ -7,6 +7,7 @@ class Attachment::MultipleComponent < ApplicationComponent
attr_reader :attached_file
attr_reader :attachments
attr_reader :champ
attr_reader :form_object_name
attr_reader :max
attr_reader :user_can_destroy
attr_reader :user_can_download
@ -14,9 +15,10 @@ class Attachment::MultipleComponent < ApplicationComponent
delegate :count, :empty?, to: :attachments, prefix: true
def initialize(champ:, attached_file:, user_can_download: false, user_can_destroy: true, max: nil)
def initialize(champ:, attached_file:, form_object_name: nil, user_can_download: false, user_can_destroy: true, max: nil)
@champ = champ
@attached_file = attached_file
@form_object_name = form_object_name
@user_can_download = user_can_download
@user_can_destroy = user_can_destroy
@max = max || DEFAULT_MAX_ATTACHMENTS

View file

@ -4,10 +4,10 @@
%ul
- each_attachment do |attachment, index|
%li{ id: dom_id(attachment) }
= render Attachment::EditComponent.new(champ:, attached_file:, attachment:, index:, as_multiple: true, user_can_destroy:, user_can_download:)
= render Attachment::EditComponent.new(champ:, attached_file:, attachment:, index:, as_multiple: true, user_can_destroy:, user_can_download:, form_object_name:)
%div{ id: empty_component_id, class: class_names("hidden": !can_attach_next?) }
= render Attachment::EditComponent.new(champ:, attached_file:, attachment: nil, index: attachments_count, user_can_destroy:)
= render Attachment::EditComponent.new(champ:, attached_file:, attachment: nil, index: attachments_count, user_can_destroy:, form_object_name:)
// single poll and refresh message for all attachments
= render Attachment::PendingPollComponent.new(attachments: attachments, poll_url:)

View file

@ -1,7 +1,7 @@
- user_can_destroy = !@champ.mandatory? || @champ.dossier.brouillon?
- user_can_download = !@champ.dossier.brouillon?
- max = [true, nil].include?(@champ.procedure&.piece_justificative_multiple?) ? Attachment::MultipleComponent::DEFAULT_MAX_ATTACHMENTS : 1
= render Attachment::MultipleComponent.new(champ: @champ, attached_file: @champ.piece_justificative_file, user_can_destroy:, user_can_download:, max:) do |c|
= render Attachment::MultipleComponent.new(champ: @champ, attached_file: @champ.piece_justificative_file, form_object_name: @form.object_name, user_can_destroy:, user_can_download:, max:) do |c|
- if @champ.type_de_champ.piece_justificative_template&.attached?
- c.with_template do
= render partial: "shared/piece_justificative_template", locals: { attachment: @champ.type_de_champ.piece_justificative_template }

View file

@ -2,4 +2,4 @@
- if @champ.type_de_champ.piece_justificative_template&.attached?
= render partial: "shared/piece_justificative_template", locals: { attachment: @champ.type_de_champ.piece_justificative_template }
= render Attachment::EditComponent.new(champ: @form.object, attached_file: @champ.piece_justificative_file, attachment: @champ.piece_justificative_file[0], user_can_destroy:)
= render Attachment::EditComponent.new(champ: @form.object, attached_file: @champ.piece_justificative_file, attachment: @champ.piece_justificative_file[0], form_object_name: @form.object_name, user_can_destroy:)

View file

@ -159,4 +159,18 @@ RSpec.describe Attachment::EditComponent, type: :component do
end
end
end
describe 'field name inference' do
it "by default generate input name directly form attached file object" do
expect(subject).to have_selector("input[name='champs_titre_identite_champ[piece_justificative_file]']")
end
context "when a form object_name is provided" do
let(:kwargs) { { form_object_name: "my_form" } }
it "generate input name from form object name and attached file object" do
expect(subject).to have_selector("input[name='my_form[piece_justificative_file]']")
end
end
end
end

View file

@ -1,7 +1,7 @@
describe EditableChamp::PieceJustificativeComponent, type: :component do
let(:champ) { create(:champ_piece_justificative, dossier: create(:dossier)) }
let(:component) {
described_class.new(form: instance_double(ActionView::Helpers::FormBuilder), champ:)
described_class.new(form: instance_double(ActionView::Helpers::FormBuilder, object_name: "dossier[champs_public_attributes]"), champ:)
}
let(:subject) {