diff --git a/app/controllers/avo/associations_controller.rb b/app/controllers/avo/associations_controller.rb
index c12183de56..f95ed4171f 100644
--- a/app/controllers/avo/associations_controller.rb
+++ b/app/controllers/avo/associations_controller.rb
@@ -12,6 +12,7 @@ class AssociationsController < BaseController
before_action :set_attachment_class, only: [:show, :index, :new, :create, :destroy]
before_action :set_attachment_resource, only: [:show, :index, :new, :create, :destroy]
before_action :set_attachment_record, only: [:create, :destroy]
+ before_action :set_attach_fields, only: [:new, :create]
before_action :authorize_index_action, only: :index
before_action :authorize_attach_action, only: :new
before_action :authorize_detach_action, only: :destroy
@@ -67,6 +68,7 @@ def create
notice: t("avo.attachment_class_attached", attachment_class: @related_resource.name)
}
else
+ flash[:error] = t("avo.attachment_failed", attachment_class: @related_resource.name)
format.turbo_stream {
render turbo_stream: turbo_stream.append("alerts", partial: "avo/partials/all_alerts")
}
@@ -78,7 +80,9 @@ def create_association
association_name = BaseResource.valid_association_name(@record, association_from_params)
perform_action_and_record_errors do
- if has_many_reflection?
+ if through_reflection? && additional_params.present?
+ new_join_record.save
+ elsif has_many_reflection? || through_reflection?
@record.send(association_name) << @attachment_record
else
@record.send(:"#{association_name}=", @attachment_record)
@@ -90,7 +94,7 @@ def create_association
def destroy
association_name = BaseResource.valid_association_name(@record, @field.for_attribute || params[:related_name])
- if @reflection.instance_of? ActiveRecord::Reflection::ThroughReflection
+ if through_reflection?
join_record.destroy!
elsif has_many_reflection?
@record.send(association_name).delete @attachment_record
@@ -190,5 +194,36 @@ def has_many_reflection?
ActiveRecord::Reflection::HasAndBelongsToManyReflection
]
end
+
+ def through_reflection?
+ @reflection.instance_of? ActiveRecord::Reflection::ThroughReflection
+ end
+
+ def additional_params
+ @additional_params ||= params[:fields].permit(@attach_fields&.map(&:id))
+ end
+
+ def set_attach_fields
+ @attach_fields = if @field.attach_fields.present?
+ Avo::FieldsExecutionContext.new(target: @field.attach_fields)
+ .detect_fields
+ .items_holder
+ .items
+ end
+ end
+
+ def new_join_record
+ @resource.fill_record(
+ @reflection.through_reflection.klass.new,
+ additional_params.merge(
+ {
+ source_foreign_key => @attachment_record.id,
+ through_foreign_key => @record.id
+ }
+ ),
+ fields: @attach_fields,
+ extra_params: [source_foreign_key, through_foreign_key]
+ )
+ end
end
end
diff --git a/app/views/avo/associations/new.html.erb b/app/views/avo/associations/new.html.erb
index 0aaecca07f..aaa4b46d60 100644
--- a/app/views/avo/associations/new.html.erb
+++ b/app/views/avo/associations/new.html.erb
@@ -18,31 +18,56 @@
} do |form| %>
<%= render Avo::ModalComponent.new do |c| %>
<% c.with_heading do %>
- <%= t 'avo.choose_item', item: @related_resource.name.downcase %>
+ <%= t 'avo.choose_item', item: @field.name.singularize.downcase %>
<% end %>
- <% if @field.is_searchable? %>
- <%= render Avo::Pro::SearchableAssociations::AutocompleteComponent.new form: form,
- classes: input_classes("w-full"),
- field: @field,
- model_key: @field.target_resource&.model_key,
- foreign_key: 'related_id',
- resource: @resource,
- view: :new
- %>
- <% else %>
-
- <%= form.select :related_id, options_for_select(@options, nil),
- {
+
+
+ <% if @field.is_searchable? %>
+ <%= field_wrapper stacked: true,
+ field: @field,
+ view: Avo::ViewInquirer.new("edit"),
+ form:,
+ index: 0,
+ resource: @resource,
+ label_for: @field.id,
+ label: @field.name.singularize.downcase do %>
+ <%= render Avo::Pro::SearchableAssociations::AutocompleteComponent.new form: form,
+ classes: input_classes("w-full"),
+ field: @field,
+ model_key: @field.target_resource&.model_key,
+ foreign_key: 'related_id',
+ resource: @resource,
+ view: :new
+ %>
+ <% end %>
+ <% else %>
+ <%= avo_edit_field :related_id,
+ as: :select,
+ form: form,
+ name: @field.name.singularize,
+ options: options_for_select(@options,
+ nil),
include_blank: t('avo.choose_an_option'),
- },
- {
- class: input_classes('w-full'),
- }
- %>
+ stacked: true,
+ classes: 'w-full'
+ %>
+ <% end %>
+ <% @attach_fields&.each_with_index do |field, index| %>
+ <%= render(Avo::Items::SwitcherComponent.new(
+ resource: @related_resource,
+ item: field,
+ index: index + 1,
+ view: @view,
+ form: form,
+ field_component_extra_args: {
+ stacked: true,
+ classes: 'w-full'}
+ )) %>
+ <% end %>
- <% end %>
+
<% c.with_controls do %>
diff --git a/lib/avo/fields/base_field.rb b/lib/avo/fields/base_field.rb
index 0f492da6a3..1e9ec2178c 100644
--- a/lib/avo/fields/base_field.rb
+++ b/lib/avo/fields/base_field.rb
@@ -242,7 +242,7 @@ def to_permitted_param
end
def record_errors
- record.nil? ? {} : record.errors
+ record.present? ? record.errors : {}
end
def type
diff --git a/lib/avo/fields/concerns/is_required.rb b/lib/avo/fields/concerns/is_required.rb
index d5d716a83f..b1885b00d3 100644
--- a/lib/avo/fields/concerns/is_required.rb
+++ b/lib/avo/fields/concerns/is_required.rb
@@ -13,7 +13,7 @@ def is_required?
private
def required_from_validators
- return false if record.nil?
+ return false unless record.present?
validators.any? do |validator|
validator.is_a? ActiveModel::Validations::PresenceValidator
diff --git a/lib/avo/fields/has_base_field.rb b/lib/avo/fields/has_base_field.rb
index 09e7795b96..018fa9096b 100644
--- a/lib/avo/fields/has_base_field.rb
+++ b/lib/avo/fields/has_base_field.rb
@@ -13,6 +13,7 @@ class HasBaseField < BaseField
attr_accessor :discreet_pagination
attr_accessor :hide_search_input
attr_reader :link_to_child_resource
+ attr_reader :attach_fields
def initialize(id, **args, &block)
super(id, **args, &block)
@@ -27,6 +28,7 @@ def initialize(id, **args, &block)
@link_to_child_resource = args[:link_to_child_resource] || false
@reloadable = args[:reloadable].present? ? args[:reloadable] : false
@linkable = args[:linkable].present? ? args[:linkable] : false
+ @attach_fields = args[:attach_fields]
end
def field_resource
diff --git a/lib/avo/fields_execution_context.rb b/lib/avo/fields_execution_context.rb
new file mode 100644
index 0000000000..d93b437b3e
--- /dev/null
+++ b/lib/avo/fields_execution_context.rb
@@ -0,0 +1,13 @@
+module Avo
+ class FieldsExecutionContext < Avo::ExecutionContext
+ include Avo::Concerns::HasItems
+
+ def detect_fields
+ self.items_holder = Avo::Resources::Items::Holder.new(parent: self)
+
+ instance_exec(&target) if target.present? && target.respond_to?(:call)
+
+ self
+ end
+ end
+end
diff --git a/lib/avo/resources/base.rb b/lib/avo/resources/base.rb
index 561910fbe2..14f6c922a9 100644
--- a/lib/avo/resources/base.rb
+++ b/lib/avo/resources/base.rb
@@ -285,14 +285,16 @@ def detect_fields
self
end
- VIEW_METHODS_MAPPING = {
- index: [:index_fields, :display_fields],
- show: [:show_fields, :display_fields],
- edit: [:edit_fields, :form_fields],
- update: [:edit_fields, :form_fields],
- new: [:new_fields, :form_fields],
- create: [:new_fields, :form_fields]
- } unless defined? VIEW_METHODS_MAPPING
+ unless defined? VIEW_METHODS_MAPPING
+ VIEW_METHODS_MAPPING = {
+ index: [:index_fields, :display_fields],
+ show: [:show_fields, :display_fields],
+ edit: [:edit_fields, :form_fields],
+ update: [:edit_fields, :form_fields],
+ new: [:new_fields, :form_fields],
+ create: [:new_fields, :form_fields]
+ }
+ end
def fetch_fields
possible_methods_for_view = VIEW_METHODS_MAPPING[view.to_sym]
@@ -334,12 +336,12 @@ def divider(label = nil)
end
# def get_actions / def get_filters / def get_scopes
- define_method "get_#{plural_entity}" do
+ define_method :"get_#{plural_entity}" do
return entity_loader(entity).bag if entity_loader(entity).present?
# ex: @actions_loader = Avo::Loaders::ActionsLoader.new
instance_variable_set(
- "@#{plural_entity}_loader",
+ :"@#{plural_entity}_loader",
"Avo::Loaders::#{plural_entity.humanize}Loader".constantize.new
)
@@ -349,8 +351,8 @@ def divider(label = nil)
end
# def get_action_arguments / def get_filter_arguments / def get_scope_arguments
- define_method "get_#{entity}_arguments" do |entity_class|
- klass = send("get_#{plural_entity}").find { |entity| entity[:class].to_s == entity_class.to_s }
+ define_method :"get_#{entity}_arguments" do |entity_class|
+ klass = send(:"get_#{plural_entity}").find { |entity| entity[:class].to_s == entity_class.to_s }
raise "Couldn't find '#{entity_class}' in the 'def #{plural_entity}' method on your '#{self.class}' resource." if klass.nil?
@@ -359,7 +361,7 @@ def divider(label = nil)
end
def hydrate(...)
- super(...)
+ super
if @record.present?
hydrate_model_with_default_values if @view&.new?
@@ -443,10 +445,14 @@ def fields_by_database_id
.to_h
end
- def fill_record(record, params, extra_params: [])
+ def fill_record(record, params, extra_params: [], fields: nil)
# Write the field values
params.each do |key, value|
- field = fields_by_database_id[key]
+ field = if fields.present?
+ fields.find { |f| f.id == key.to_sym }
+ else
+ fields_by_database_id[key]
+ end
next unless field.present?
@@ -601,7 +607,7 @@ def description_attributes
end
def entity_loader(entity)
- instance_variable_get("@#{entity.to_s.pluralize}_loader")
+ instance_variable_get(:"@#{entity.to_s.pluralize}_loader")
end
def record_param
diff --git a/lib/generators/avo/templates/locales/avo.ar.yml b/lib/generators/avo/templates/locales/avo.ar.yml
index 24403ccbd6..61aaca4e14 100644
--- a/lib/generators/avo/templates/locales/avo.ar.yml
+++ b/lib/generators/avo/templates/locales/avo.ar.yml
@@ -21,6 +21,7 @@ ar:
attachment_class_attached: "%{attachment_class} تم ربط"
attachment_class_detached: "%{attachment_class} تم فصل"
attachment_destroyed: تم حذف المرفق
+ attachment_failed: فشل في إرفاق %{attachment_class}
cancel: إلغاء
choose_a_country: اختر دولة
choose_an_option: اختر خيارًا
diff --git a/lib/generators/avo/templates/locales/avo.de.yml b/lib/generators/avo/templates/locales/avo.de.yml
index b4bcb63e60..5b2a462d84 100644
--- a/lib/generators/avo/templates/locales/avo.de.yml
+++ b/lib/generators/avo/templates/locales/avo.de.yml
@@ -16,6 +16,7 @@ de:
attach_item: "%{item} anhängen"
attachment_class_attached: "%{attachment_class} angehängt."
attachment_class_detached: "%{attachment_class} abgehängt."
+ attachment_failed: "Kon %{attachment_class} niet bijvoegen"
attachment_destroyed: Anhang gelöscht
cancel: Abbrechen
choose_a_country: Land auswählen
diff --git a/lib/generators/avo/templates/locales/avo.en.yml b/lib/generators/avo/templates/locales/avo.en.yml
index ff33b02936..bfdb235087 100644
--- a/lib/generators/avo/templates/locales/avo.en.yml
+++ b/lib/generators/avo/templates/locales/avo.en.yml
@@ -15,6 +15,7 @@ en:
attachment_class_attached: "%{attachment_class} attached."
attachment_class_detached: "%{attachment_class} detached."
attachment_destroyed: Attachment destroyed
+ attachment_failed: Failed to attach %{attachment_class}
cancel: Cancel
choose_a_country: Choose a country
choose_an_option: Choose an option
diff --git a/lib/generators/avo/templates/locales/avo.es.yml b/lib/generators/avo/templates/locales/avo.es.yml
index 09a6615d36..5b63351c2f 100644
--- a/lib/generators/avo/templates/locales/avo.es.yml
+++ b/lib/generators/avo/templates/locales/avo.es.yml
@@ -17,6 +17,7 @@ es:
attachment_class_attached: "%{attachment_class} adjuntado/a."
attachment_class_detached: "%{attachment_class} adjuntado/a."
attachment_destroyed: Adjunto eliminado
+ attachment_failed: No se pudo adjuntar %{attachment_class}
cancel: Cancelar
choose_a_country: Elige un país
choose_an_option: Elige una opción
diff --git a/lib/generators/avo/templates/locales/avo.fr.yml b/lib/generators/avo/templates/locales/avo.fr.yml
index 421fadddc0..a46a705ef1 100644
--- a/lib/generators/avo/templates/locales/avo.fr.yml
+++ b/lib/generators/avo/templates/locales/avo.fr.yml
@@ -17,6 +17,7 @@ fr:
attachment_class_attached: "%{attachment_class} attaché."
attachment_class_detached: "%{attachment_class} détaché."
attachment_destroyed: Pièce jointe détruite
+ attachment_failed: Échec de l'ajout de %{attachment_class}
cancel: Annuler
choose_a_country: Sélectionnez un pays
choose_an_option: Sélectionnez une option
diff --git a/lib/generators/avo/templates/locales/avo.it.yml b/lib/generators/avo/templates/locales/avo.it.yml
index 6fdf8cefb5..727906ba51 100644
--- a/lib/generators/avo/templates/locales/avo.it.yml
+++ b/lib/generators/avo/templates/locales/avo.it.yml
@@ -16,6 +16,7 @@ it:
attach_item: Allega %{item}
attachment_class_attached: "%{attachment_class} allegato."
attachment_class_detached: "%{attachment_class} staccato."
+ attachment_failed: "Impossibile allegare %{attachment_class}"
attachment_destroyed: Allegato distrutto
cancel: Annulla
choose_a_country: Scegli un paese
diff --git a/lib/generators/avo/templates/locales/avo.ja.yml b/lib/generators/avo/templates/locales/avo.ja.yml
index 3e8699032d..6309ff8c16 100644
--- a/lib/generators/avo/templates/locales/avo.ja.yml
+++ b/lib/generators/avo/templates/locales/avo.ja.yml
@@ -17,6 +17,7 @@ ja:
attachment_class_attached: "%{attachment_class}をアタッチしました。"
attachment_class_detached: "%{attachment_class}をデタッチしました。"
attachment_destroyed: アタッチは削除されました
+ attachment_failed: "%{attachment_class}の添付に失敗しました"
cancel: キャンセル
choose_a_country: 国を選択
choose_an_option: オプションを選択
diff --git a/lib/generators/avo/templates/locales/avo.nb.yml b/lib/generators/avo/templates/locales/avo.nb.yml
index 3f280eebe1..c0f62cca89 100644
--- a/lib/generators/avo/templates/locales/avo.nb.yml
+++ b/lib/generators/avo/templates/locales/avo.nb.yml
@@ -17,6 +17,7 @@ nb:
attachment_class_attached: "%{attachment_class} lagt til."
attachment_class_detached: "%{attachment_class} fjernet."
attachment_destroyed: Vedlett slettet
+ attachment_failed: Kunne ikke legge ved %{attachment_class}
cancel: Avbryt
choose_a_country: Velg et land
choose_an_option: Velg et alternativ
diff --git a/lib/generators/avo/templates/locales/avo.nl.yml b/lib/generators/avo/templates/locales/avo.nl.yml
index 0be9c8608d..3b3b137b09 100644
--- a/lib/generators/avo/templates/locales/avo.nl.yml
+++ b/lib/generators/avo/templates/locales/avo.nl.yml
@@ -16,6 +16,7 @@ nl:
attach_item: "%{item} bijvoegen"
attachment_class_attached: "%{attachment_class} bijgevoegd."
attachment_class_detached: "%{attachment_class} losgekoppeld."
+ attachment_failed: "Kon %{attachment_class} niet bijvoegen"
attachment_destroyed: Bijlage verwijderd
cancel: Annuleren
choose_a_country: Kies een land
diff --git a/lib/generators/avo/templates/locales/avo.nn.yml b/lib/generators/avo/templates/locales/avo.nn.yml
index eaaef50477..47eaddd644 100644
--- a/lib/generators/avo/templates/locales/avo.nn.yml
+++ b/lib/generators/avo/templates/locales/avo.nn.yml
@@ -17,6 +17,7 @@ nn:
attachment_class_attached: "%{attachment_class} lagt til."
attachment_class_detached: "%{attachment_class} fjerna."
attachment_destroyed: Vedlegg sletta
+ attachment_failed: Klarte ikkje å legge ved %{attachment_class}
cancel: Avbryt
choose_a_country: Vel eit land
choose_an_option: Vel eit alternativ
diff --git a/lib/generators/avo/templates/locales/avo.pl.yml b/lib/generators/avo/templates/locales/avo.pl.yml
index fd34f819f6..9b59e93ce3 100644
--- a/lib/generators/avo/templates/locales/avo.pl.yml
+++ b/lib/generators/avo/templates/locales/avo.pl.yml
@@ -16,6 +16,7 @@ pl:
attach_item: Załącz %{item}
attachment_class_attached: "%{attachment_class} załączony."
attachment_class_detached: "%{attachment_class} odłączony."
+ attachment_failed: "Nie udało się dołączyć %{attachment_class}"
attachment_destroyed: Załącznik usunięty
cancel: Anuluj
choose_a_country: Wybierz kraj
diff --git a/lib/generators/avo/templates/locales/avo.pt-BR.yml b/lib/generators/avo/templates/locales/avo.pt-BR.yml
index f9834422f1..8986fe935d 100644
--- a/lib/generators/avo/templates/locales/avo.pt-BR.yml
+++ b/lib/generators/avo/templates/locales/avo.pt-BR.yml
@@ -17,6 +17,7 @@ pt-BR:
attachment_class_attached: "%{attachment_class} anexado."
attachment_class_detached: "%{attachment_class} separado."
attachment_destroyed: Anexo destruído
+ attachment_failed: Não foi possível anexar %{attachment_class}
cancel: Cancelar
choose_a_country: Escolha um país
choose_an_option: Escolha uma opção
diff --git a/lib/generators/avo/templates/locales/avo.pt.yml b/lib/generators/avo/templates/locales/avo.pt.yml
index 171e5bc524..8a276aff5b 100644
--- a/lib/generators/avo/templates/locales/avo.pt.yml
+++ b/lib/generators/avo/templates/locales/avo.pt.yml
@@ -17,6 +17,7 @@ pt:
attachment_class_attached: "%{attachment_class} anexado."
attachment_class_detached: "%{attachment_class} separado."
attachment_destroyed: Anexo destruído
+ attachment_failed: Não foi possível anexar %{attachment_class}
cancel: Cancelar
choose_a_country: Escolha um país
choose_an_option: Escolha uma opção
diff --git a/lib/generators/avo/templates/locales/avo.ro.yml b/lib/generators/avo/templates/locales/avo.ro.yml
index 13554f9815..d9bbf96dde 100644
--- a/lib/generators/avo/templates/locales/avo.ro.yml
+++ b/lib/generators/avo/templates/locales/avo.ro.yml
@@ -18,6 +18,7 @@ ro:
attachment_class_attached: "%{attachment_class} anexat."
attachment_class_detached: "%{attachment_class} separat."
attachment_destroyed: Atașamentul a fost distrus
+ attachment_failed: Nu s-a reușit atașarea %{attachment_class}
cancel: Anulează
choose_a_country: Alege o țară
choose_an_option: Alege o opțiune
diff --git a/lib/generators/avo/templates/locales/avo.ru.yml b/lib/generators/avo/templates/locales/avo.ru.yml
index ff1c7101b3..7cb2434420 100644
--- a/lib/generators/avo/templates/locales/avo.ru.yml
+++ b/lib/generators/avo/templates/locales/avo.ru.yml
@@ -16,6 +16,7 @@ ru:
attach_item: Прикрепить %{item}
attachment_class_attached: "%{attachment_class} прикреплено."
attachment_class_detached: "%{attachment_class} отсоединено."
+ attachment_failed: "Не удалось прикрепить %{attachment_class}"
attachment_destroyed: Вложение удалено
cancel: Отмена
choose_a_country: Выберите страну
diff --git a/lib/generators/avo/templates/locales/avo.tr.yml b/lib/generators/avo/templates/locales/avo.tr.yml
index 6f7d1f6e02..0b43ddff13 100644
--- a/lib/generators/avo/templates/locales/avo.tr.yml
+++ b/lib/generators/avo/templates/locales/avo.tr.yml
@@ -17,6 +17,7 @@ tr:
attachment_class_attached: "%{attachment_class} ilişkilendirildi."
attachment_class_detached: "%{attachment_class} ilişkisi kesildi."
attachment_destroyed: Ek silindi
+ attachment_failed: "%{attachment_class} eklenemedi"
cancel: İptal et
choose_a_country: Bir ülke seç
choose_an_option: Bir seçenek seç
diff --git a/lib/generators/avo/templates/locales/avo.uk.yml b/lib/generators/avo/templates/locales/avo.uk.yml
index 6eb443eb83..23f191f89f 100644
--- a/lib/generators/avo/templates/locales/avo.uk.yml
+++ b/lib/generators/avo/templates/locales/avo.uk.yml
@@ -16,6 +16,7 @@ uk:
attach_item: Прикріпити %{item}
attachment_class_attached: "%{attachment_class} прикріплено."
attachment_class_detached: "%{attachment_class} відкріплено."
+ attachment_failed: "Не вдалося прикріпити %{attachment_class}"
attachment_destroyed: Вкладення знищено
cancel: Скасувати
choose_a_country: Виберіть країну
diff --git a/lib/generators/avo/templates/locales/avo.zh.yml b/lib/generators/avo/templates/locales/avo.zh.yml
index c6766493ff..18f253cbd6 100644
--- a/lib/generators/avo/templates/locales/avo.zh.yml
+++ b/lib/generators/avo/templates/locales/avo.zh.yml
@@ -16,6 +16,7 @@ zh:
attach_item: 附加 %{item}
attachment_class_attached: "%{attachment_class} 已附加。"
attachment_class_detached: "%{attachment_class} 已分离。"
+ attachment_failed: "无法附加 %{attachment_class}"
attachment_destroyed: 附件已删除
cancel: 取消
choose_a_country: 选择一个国家
diff --git a/spec/dummy/app/avo/resources/store.rb b/spec/dummy/app/avo/resources/store.rb
index b596c06003..6343a628b1 100644
--- a/spec/dummy/app/avo/resources/store.rb
+++ b/spec/dummy/app/avo/resources/store.rb
@@ -11,5 +11,16 @@ def fields
# Example for error message when resource is missing
field :location, as: :has_one
end
+
+ field :patrons, as: :has_many, through: :patronships,
+ translation_key: "patrons",
+ attach_fields: -> {
+ if ENV["TEST_FILL_JOIN_RECORD"]
+ field :review, as: :text,
+ update_using: -> { ">> #{value} <<" }
+ else
+ field :review, as: :text
+ end
+ }
end
end
diff --git a/spec/dummy/app/models/store.rb b/spec/dummy/app/models/store.rb
index cb3e045416..706e14ce32 100644
--- a/spec/dummy/app/models/store.rb
+++ b/spec/dummy/app/models/store.rb
@@ -10,4 +10,7 @@
#
class Store < ApplicationRecord
has_one :location
+
+ has_many :patronships, class_name: :StorePatron
+ has_many :patrons, through: :patronships, class_name: :User, source: :user
end
diff --git a/spec/dummy/app/models/store_patron.rb b/spec/dummy/app/models/store_patron.rb
new file mode 100644
index 0000000000..96c5694c74
--- /dev/null
+++ b/spec/dummy/app/models/store_patron.rb
@@ -0,0 +1,6 @@
+class StorePatron < ApplicationRecord
+ belongs_to :store
+ belongs_to :user
+
+ validates :review, presence: true
+end
diff --git a/spec/dummy/config/locales/avo.en.yml b/spec/dummy/config/locales/avo.en.yml
index 69fad96971..ed04e5b7f2 100644
--- a/spec/dummy/config/locales/avo.en.yml
+++ b/spec/dummy/config/locales/avo.en.yml
@@ -16,6 +16,7 @@ en:
attach_item: Attach %{item}
attachment_class_attached: "%{attachment_class} attached."
attachment_class_detached: "%{attachment_class} detached."
+ attachment_failed: "Failed to attach %{attachment_class}"
attachment_destroyed: Attachment destroyed
cancel: Cancel
choose_a_country: Choose a country
diff --git a/spec/dummy/db/migrate/20240724090242_create_store_patrons.rb b/spec/dummy/db/migrate/20240724090242_create_store_patrons.rb
new file mode 100644
index 0000000000..f0ec56d29a
--- /dev/null
+++ b/spec/dummy/db/migrate/20240724090242_create_store_patrons.rb
@@ -0,0 +1,11 @@
+class CreateStorePatrons < ActiveRecord::Migration[6.1]
+ def change
+ create_table :store_patrons do |t|
+ t.integer :store_id
+ t.integer :user_id
+ t.string :review
+
+ t.timestamps
+ end
+ end
+end
diff --git a/spec/dummy/db/schema.rb b/spec/dummy/db/schema.rb
index 5212241826..b73ba37948 100644
--- a/spec/dummy/db/schema.rb
+++ b/spec/dummy/db/schema.rb
@@ -171,7 +171,7 @@
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "price_cents", default: 0, null: false
- t.string "price_currency", default: "'USD'::character varying", null: false
+ t.string "price_currency", default: "USD", null: false
end
create_table "projects", force: :cascade do |t|
@@ -208,6 +208,14 @@
t.index ["user_id"], name: "index_reviews_on_user_id"
end
+ create_table "store_patrons", force: :cascade do |t|
+ t.integer "store_id"
+ t.integer "user_id"
+ t.string "review"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ end
+
create_table "stores", force: :cascade do |t|
t.string "name"
t.string "size"
diff --git a/spec/features/avo/fields_methods_for_views_spec.rb b/spec/features/avo/fields_methods_for_views_spec.rb
index 3429c28273..fc4b12787d 100644
--- a/spec/features/avo/fields_methods_for_views_spec.rb
+++ b/spec/features/avo/fields_methods_for_views_spec.rb
@@ -175,7 +175,7 @@ def form_fields
click_on "Attach link"
- expect(page).to have_text "Choose course link"
+ expect(page).to have_text "Choose link"
select attach_link.link, from: "fields_related_id"
diff --git a/spec/system/avo/attach_with_additional_fields_spec.rb b/spec/system/avo/attach_with_additional_fields_spec.rb
new file mode 100644
index 0000000000..e03d06be93
--- /dev/null
+++ b/spec/system/avo/attach_with_additional_fields_spec.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+require "rails_helper"
+
+RSpec.describe "Attach with extra fields", type: :system do
+ let!(:store) { create(:store) }
+ let!(:user) { create :user }
+ let!(:url) { "/admin/resources/stores/#{store.id}/patrons/new?view=show" }
+
+ it "allows to pass in data for extra fields" do
+ visit url
+ expect(page).to have_selector "input#fields_review"
+ expect(page).to have_selector "select#fields_related_id"
+
+ select user.name
+
+ expect {
+ click_button "Attach"
+ }.not_to change(StorePatron, :count)
+
+ expect(page).to_not have_text "Failed to attach User"
+
+ select user.name
+ fill_in id: "fields_review", with: "Toilet paper is phenomenal here."
+
+ expect(page).to have_selector "label[for='fields_related_id']", text: "PATRON"
+ expect {
+ click_button "Attach"
+ }.to change(StorePatron, :count).by 1
+ expect(page).to have_text "User attached"
+ end
+
+ it "saves attachment adhering to options like update_using" do
+ ENV["TEST_FILL_JOIN_RECORD"] = "1"
+ visit url
+ expect(page).to have_selector "input#fields_review"
+ expect(page).to have_selector "select#fields_related_id"
+
+ select user.name
+ fill_in id: "fields_review", with: "Toilet paper is phenomenal here."
+
+ expect(page).to have_selector "label[for='fields_related_id']", text: "PATRON"
+ expect {
+ click_button "Attach"
+ }.to change(StorePatron, :count)
+ expect(store.patronships.first.review).to eq ">> Toilet paper is phenomenal here. <<"
+ end
+end
diff --git a/spec/system/avo/for_attribute_spec.rb b/spec/system/avo/for_attribute_spec.rb
index 21e8081c17..4cc73cb3c2 100644
--- a/spec/system/avo/for_attribute_spec.rb
+++ b/spec/system/avo/for_attribute_spec.rb
@@ -54,7 +54,7 @@
click_on "Attach even review"
- expect(page).to have_text "Choose review"
+ expect(page).to have_text "Choose even review"
expect(page).to have_select "fields_related_id", selected: "Choose an option"
select review.tiny_name, from: "fields_related_id"
diff --git a/spec/system/avo/has_one_field_name_spec.rb b/spec/system/avo/has_one_field_name_spec.rb
index 0a53550765..532bf00842 100644
--- a/spec/system/avo/has_one_field_name_spec.rb
+++ b/spec/system/avo/has_one_field_name_spec.rb
@@ -25,7 +25,7 @@
wait_for_loaded
- expect(page).to have_text "Choose post"
+ expect(page).to have_text "Choose main post"
expect(page).to have_select "fields_related_id", selected: "Choose an option"
select post.name, from: "fields_related_id"