<%= f.input :workshop_id,
- collection: f.object.workshop.present? ? [[ f.object.workshop.title, f.object.workshop.id]] : [],
+ collection: f.object.workshop.present? ? [[ f.object.workshop.remote_search_label[:label], f.object.workshop.id]] : [],
include_blank: true,
required: true,
input_html: {
diff --git a/app/views/workshop_variation_ideas/_form.html.erb b/app/views/workshop_variation_ideas/_form.html.erb
index 5379ad976..c9ca35437 100644
--- a/app/views/workshop_variation_ideas/_form.html.erb
+++ b/app/views/workshop_variation_ideas/_form.html.erb
@@ -35,7 +35,7 @@
<%= f.input :workshop_id,
- collection: f.object.workshop.present? ? [[ f.object.workshop.title, f.object.workshop.id]] : [],
+ collection: f.object.workshop.present? ? [[ f.object.workshop.remote_search_label[:label], f.object.workshop.id]] : [],
include_blank: true,
required: true,
input_html: {
diff --git a/app/views/workshop_variations/_form.html.erb b/app/views/workshop_variations/_form.html.erb
index 9709f0a5e..601ab16bc 100644
--- a/app/views/workshop_variations/_form.html.erb
+++ b/app/views/workshop_variations/_form.html.erb
@@ -14,7 +14,7 @@
<% else %>
<%= f.input :workshop_id,
- collection: f.object.workshop.present? ? [[ f.object.workshop.title, f.object.workshop.id]] : [],
+ collection: f.object.workshop.present? ? [[ f.object.workshop.remote_search_label[:label], f.object.workshop.id]] : [],
include_blank: true,
required: true,
input_html: {
diff --git a/app/views/workshops/edit.html.erb b/app/views/workshops/edit.html.erb
index 1794ed784..de32c8f51 100644
--- a/app/views/workshops/edit.html.erb
+++ b/app/views/workshops/edit.html.erb
@@ -5,7 +5,7 @@
<%= link_to "Workshops", workshops_path, class: "text-sm text-gray-500 hover:text-gray-700 px-2 py-1" %>
<%= link_to "View", workshop_path(@workshop), class: "text-sm text-gray-500 hover:text-gray-700 px-2 py-1" %>
-
Edit workshop
+
Edit workshop: <%= @workshop.remote_search_label[:label] %>
diff --git a/db/seeds/dummy_dev_seeds.rb b/db/seeds/dummy_dev_seeds.rb
index 9cf0f20d0..7a0e4388b 100644
--- a/db/seeds/dummy_dev_seeds.rb
+++ b/db/seeds/dummy_dev_seeds.rb
@@ -322,6 +322,34 @@
Workshop.where(title: workshop_data[:title]).first_or_create!(workshop_data)
end
+# Duplicate-title workshops to exercise ID disambiguation in search
+[
+ {
+ title: "Healing Through Color",
+ windows_type: adult_wt,
+ full_name: "Maria Torres",
+ month: 3,
+ year: 2020,
+ description: "Uses color mixing and painting to help participants explore emotions and find calm. Participants create a personal color wheel that maps feelings to colors.",
+ published: true,
+ searchable: true,
+ created_by: admin_user
+ },
+ {
+ title: "Healing Through Color",
+ windows_type: adult_wt,
+ full_name: "James Whitfield",
+ month: 9,
+ year: 2022,
+ description: "A revised version exploring color as a pathway to emotional awareness. Participants blend watercolors while discussing how color connects to memory and healing.",
+ published: true,
+ searchable: true,
+ created_by: admin_user
+ }
+].each do |workshop_data|
+ Workshop.create!(workshop_data)
+end
+
puts "Assigning workshop categories and sectors…"
workshops = Workshop.all
categories = Category.all.to_a
diff --git a/spec/models/workshop_spec.rb b/spec/models/workshop_spec.rb
index 6634cbb60..f5f326352 100644
--- a/spec/models/workshop_spec.rb
+++ b/spec/models/workshop_spec.rb
@@ -119,5 +119,68 @@
end
end
+ describe "#remote_search_label" do
+ it "returns title with windows type short_name" do
+ record = create(:workshop, title: "Art Therapy", windows_type: create(:windows_type, :children))
+
+ expect(record.remote_search_label).to eq({ id: record.id, label: "Art Therapy (CHILDREN)" })
+ end
+
+ it "returns just the title when no windows type" do
+ record = create(:workshop, title: "Art Therapy", windows_type: nil)
+
+ expect(record.remote_search_label).to eq({ id: record.id, label: "Art Therapy" })
+ end
+ end
+
+ describe ".resolve_duplicate_labels" do
+ it "omits id when labels are unique" do
+ wt = create(:windows_type, :adult)
+ w1 = create(:workshop, title: "Art Therapy", windows_type: wt)
+ w2 = create(:workshop, title: "Music Therapy", windows_type: wt)
+
+ labels = Workshop.resolve_duplicate_labels([ w1, w2 ].map(&:remote_search_label))
+
+ expect(labels).to contain_exactly(
+ { id: w1.id, label: "Art Therapy (ADULT)" },
+ { id: w2.id, label: "Music Therapy (ADULT)" }
+ )
+ end
+
+ it "appends id only to duplicate labels" do
+ wt = create(:windows_type, :adult)
+ w1 = create(:workshop, title: "Art Therapy", windows_type: wt)
+ w2 = create(:workshop, title: "Art Therapy", windows_type: wt)
+ w3 = create(:workshop, title: "Music Therapy", windows_type: wt)
+
+ labels = Workshop.resolve_duplicate_labels([ w1, w2, w3 ].map(&:remote_search_label))
+
+ expect(labels).to contain_exactly(
+ { id: w1.id, label: "Art Therapy (ADULT) ##{w1.id}" },
+ { id: w2.id, label: "Art Therapy (ADULT) ##{w2.id}" },
+ { id: w3.id, label: "Music Therapy (ADULT)" }
+ )
+ end
+ end
+
+ describe ".remote_search" do
+ it "finds workshops matching the query" do
+ matching = create(:workshop, title: "Healing Through Art")
+ create(:workshop, title: "Unrelated Workshop")
+
+ results = Workshop.remote_search("Healing")
+
+ expect(results).to contain_exactly(matching)
+ end
+
+ it "eager loads windows_type to avoid N+1" do
+ create(:workshop, title: "Healing Through Art")
+
+ results = Workshop.remote_search("Healing")
+
+ expect(results.includes_values).to include(:windows_type)
+ end
+ end
+
# Add tests for scopes, methods like #rating, #log_count, SearchCop etc.
end