diff --git a/app/controllers/partners/children_controller.rb b/app/controllers/partners/children_controller.rb
index 64b8033934..0c2c42ae28 100644
--- a/app/controllers/partners/children_controller.rb
+++ b/app/controllers/partners/children_controller.rb
@@ -88,11 +88,11 @@ def child_params
:first_name,
:gender,
:health_insurance,
- :item_needed_diaperid,
:last_name,
:race,
:archived,
- child_lives_with: []
+ child_lives_with: [],
+ needed_item_ids: []
)
end
diff --git a/app/controllers/partners/family_requests_controller.rb b/app/controllers/partners/family_requests_controller.rb
index ff91b4b9bc..fdcd0a5493 100644
--- a/app/controllers/partners/family_requests_controller.rb
+++ b/app/controllers/partners/family_requests_controller.rb
@@ -23,9 +23,12 @@ def create
end
end
- children = current_partner.children.active.where(id: children_ids).where.not(item_needed_diaperid: [nil, 0])
+ children = current_partner.children.active
+ .where(id: children_ids)
+ .joins(:needed_items)
+ .select('children.*', :item_id)
- children_grouped_by_item_id = children.group_by(&:item_needed_diaperid)
+ children_grouped_by_item_id = children.group_by(&:item_id)
family_requests_attributes = children_grouped_by_item_id.map do |item_id, item_requested_children|
{ item_id: item_id, person_count: item_requested_children.size, children: item_requested_children }
end
diff --git a/app/models/partners/child.rb b/app/models/partners/child.rb
index 1421bd47a1..e0899d29a9 100644
--- a/app/models/partners/child.rb
+++ b/app/models/partners/child.rb
@@ -25,6 +25,7 @@ class Child < Base
serialize :child_lives_with, Array
belongs_to :family
has_many :child_item_requests, dependent: :destroy
+ has_and_belongs_to_many :needed_items, class_name: 'Item'
include Filterable
include Exportable
@@ -88,7 +89,7 @@ def display_name
def self.csv_export_headers
%w[
id first_name last_name date_of_birth gender child_lives_with race agency_child_id
- health_insurance comments created_at updated_at family_id item_needed_diaperid active archived
+ health_insurance comments created_at updated_at family_id needed_item_ids active archived
].freeze
end
@@ -107,7 +108,7 @@ def csv_export_attributes
created_at,
updated_at,
family_id,
- item_needed_diaperid,
+ needed_item_ids,
active,
archived
]
@@ -115,3 +116,4 @@ def csv_export_attributes
end
end
+# TODO: drop item_needed_diaperid after issue #3797 released to prod
diff --git a/app/views/partners/children/_child.json.jbuilder b/app/views/partners/children/_child.json.jbuilder
index 63ae89cc65..7368b28458 100644
--- a/app/views/partners/children/_child.json.jbuilder
+++ b/app/views/partners/children/_child.json.jbuilder
@@ -1,2 +1,2 @@
-json.extract! child, :id, :first_name, :last_name, :date_of_birth, :gender, :child_lives_with, :race, :agency_child_id, :health_insurance, :item_needed_diaperid, :comments, :created_at, :updated_at
+json.extract! child, :id, :first_name, :last_name, :date_of_birth, :gender, :child_lives_with, :race, :agency_child_id, :health_insurance, :needed_item_ids, :comments, :created_at, :updated_at
json.url child_url(child, format: :json)
diff --git a/app/views/partners/children/_form.html.erb b/app/views/partners/children/_form.html.erb
index 5a8795941b..7cfc9747b7 100644
--- a/app/views/partners/children/_form.html.erb
+++ b/app/views/partners/children/_form.html.erb
@@ -17,10 +17,10 @@
<%= form.text_field :last_name, class: "form-control" %>
<%= form.label :item_needed, "Diaper/Item Used" %>
- <%= form.select :item_needed_diaperid, @formatted_requestable_items,
- {include_blank: 'Select an item'},
- {class: 'form-control'} %>
-
+ (select multiple by holding `ctrl`)
+ <%= form.select :needed_item_ids, @formatted_requestable_items,
+ {include_blank: false, include_hidden: false, selected: child.needed_item_ids},
+ {class: 'form-control', multiple: true} %>
<%= form.input :date_of_birth, as: :date, start_year: 20.years.ago.year, end_year: Time.current.year, label: "Date of Birth" %>
<%= form.input :gender, collection: ["Male", "Female"], class: "form-control" %>
diff --git a/app/views/partners/children/show.html.erb b/app/views/partners/children/show.html.erb
index 45e28aa0ed..75019c664f 100644
--- a/app/views/partners/children/show.html.erb
+++ b/app/views/partners/children/show.html.erb
@@ -59,7 +59,11 @@
<%= @child.health_insurance %>
Item needed:
- <%= current_partner.organization.item_id_to_display_string_map[@child.item_needed_diaperid] %>
+
+ <%= @child.needed_item_ids.map{|item_id|
+ current_partner.organization.item_id_to_display_string_map[item_id]
+ }.join(', ') %>
+
Comments:
<%= @child.comments %>
diff --git a/app/views/partners/family_requests/_list.html.erb b/app/views/partners/family_requests/_list.html.erb
index 2b350f25b1..26067ffc08 100644
--- a/app/views/partners/family_requests/_list.html.erb
+++ b/app/views/partners/family_requests/_list.html.erb
@@ -18,15 +18,17 @@
<%= child.first_name %> <%= child.last_name %>
- <% if child.item_needed_diaperid %>
- <%= current_partner.organization.item_id_to_display_string_map[child.item_needed_diaperid] %>
+ <% if child.needed_item_ids.present? %>
+ <%= child.needed_item_ids.map{|item_id|
+ current_partner.organization.item_id_to_display_string_map[item_id]
+ }.join(', ') %>
<% else %>
<%= "N/A" %>
<% end %>
|
- <% if child.item_needed_diaperid %>
+ <% if child.needed_item_ids.present? %>
<%= check_box_tag "child-#{child.id}", child.active, child.active,
class: "custom-control-input",
id: "child-#{child.id}" %>
diff --git a/db/migrate/20240221072117_create_join_table_child_item.rb b/db/migrate/20240221072117_create_join_table_child_item.rb
new file mode 100644
index 0000000000..5be9339cfc
--- /dev/null
+++ b/db/migrate/20240221072117_create_join_table_child_item.rb
@@ -0,0 +1,12 @@
+class CreateJoinTableChildItem < ActiveRecord::Migration[7.0]
+ def change
+ create_table :children_items do |t|
+ t.references :child, null: false, foreign_key: true
+ t.references :item, null: false, foreign_key: true
+
+ t.timestamps
+ end
+
+ add_index :children_items, [:child_id, :item_id], unique: true
+ end
+end
diff --git a/db/migrate/20240221072118_populate_needed_items.rb b/db/migrate/20240221072118_populate_needed_items.rb
new file mode 100644
index 0000000000..1282600cc3
--- /dev/null
+++ b/db/migrate/20240221072118_populate_needed_items.rb
@@ -0,0 +1,7 @@
+class PopulateNeededItems < ActiveRecord::Migration[7.0]
+ def change
+ Partners::Child.find_each do |child|
+ child.needed_item_ids = [child.item_needed_diaperid] if child.item_needed_diaperid.present?
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index ec0fb34d6a..af530fefd2 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.0].define(version: 2024_02_07_202431) do
+ActiveRecord::Schema[7.0].define(version: 2024_02_21_072118) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -188,6 +188,16 @@
t.index ["family_id"], name: "index_children_on_family_id"
end
+ create_table "children_items", force: :cascade do |t|
+ t.bigint "child_id", null: false
+ t.bigint "item_id", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.index ["child_id", "item_id"], name: "index_children_items_on_child_id_and_item_id", unique: true
+ t.index ["child_id"], name: "index_children_items_on_child_id"
+ t.index ["item_id"], name: "index_children_items_on_item_id"
+ end
+
create_table "counties", force: :cascade do |t|
t.string "name"
t.string "region"
@@ -861,6 +871,8 @@
add_foreign_key "child_item_requests", "children"
add_foreign_key "child_item_requests", "item_requests"
add_foreign_key "children", "families"
+ add_foreign_key "children_items", "children"
+ add_foreign_key "children_items", "items"
add_foreign_key "distributions", "partners"
add_foreign_key "distributions", "storage_locations"
add_foreign_key "donations", "manufacturers"
diff --git a/db/seeds.rb b/db/seeds.rb
index 7da24334b8..f51f19896c 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -304,7 +304,7 @@ def random_record_for_org(org, klass)
comments: Faker::Lorem.paragraph,
active: Faker::Boolean.boolean,
archived: false,
- item_needed_diaperid: p.organization.item_id_to_display_string_map.key(Partners::Child::CHILD_ITEMS.sample)
+ needed_item_ids: [p.organization.item_id_to_display_string_map.key(Partners::Child::CHILD_ITEMS.sample)]
)
end
@@ -322,7 +322,7 @@ def random_record_for_org(org, klass)
comments: Faker::Lorem.paragraph,
active: Faker::Boolean.boolean,
archived: false,
- item_needed_diaperid: p.organization.item_id_to_display_string_map.key(Partners::Child::CHILD_ITEMS.sample)
+ needed_item_ids: [p.organization.item_id_to_display_string_map.key(Partners::Child::CHILD_ITEMS.sample)]
)
end
end
diff --git a/spec/factories/partners/child.rb b/spec/factories/partners/child.rb
index 6b4b60b43c..8b4339aeaa 100644
--- a/spec/factories/partners/child.rb
+++ b/spec/factories/partners/child.rb
@@ -9,6 +9,6 @@
first_name { Faker::Name.first_name }
last_name { Faker::Name.last_name }
gender { Faker::Gender.binary_type }
- item_needed_diaperid { Item.all.sample.id }
+ needed_item_ids { [Item.all.sample.id] }
end
end
diff --git a/spec/models/partners/child_spec.rb b/spec/models/partners/child_spec.rb
index c8ace29762..ce6bdcd82b 100644
--- a/spec/models/partners/child_spec.rb
+++ b/spec/models/partners/child_spec.rb
@@ -25,6 +25,7 @@
describe 'associations' do
it { should belong_to(:family) }
it { should have_many(:child_item_requests).dependent(:destroy) }
+ it { should have_and_belong_to_many(:needed_items).class_name('Item') }
end
describe "#display_name" do
diff --git a/spec/requests/partners/children_requests_spec.rb b/spec/requests/partners/children_requests_spec.rb
index ca42e7386a..cd3dcf1e75 100644
--- a/spec/requests/partners/children_requests_spec.rb
+++ b/spec/requests/partners/children_requests_spec.rb
@@ -15,7 +15,7 @@
agency_child_id: "Agency McAgence",
health_insurance: "Private insurance",
comments: "Some comment",
- item_needed_diaperid: nil,
+ needed_item_ids: nil,
active: true,
archived: false,
family: family)
@@ -31,7 +31,7 @@
agency_child_id: "Agency McAgence",
health_insurance: "Private insurance",
comments: "Some comment",
- item_needed_diaperid: nil,
+ needed_item_ids: nil,
active: true,
archived: false,
family: family)
@@ -51,7 +51,7 @@
headers = {"Accept" => "text/csv", "Content-Type" => "text/csv"}
get partners_children_path, headers: headers
csv = <<~CSV
- id,first_name,last_name,date_of_birth,gender,child_lives_with,race,agency_child_id,health_insurance,comments,created_at,updated_at,family_id,item_needed_diaperid,active,archived
+ id,first_name,last_name,date_of_birth,gender,child_lives_with,race,agency_child_id,health_insurance,comments,created_at,updated_at,family_id,needed_item_ids,active,archived
#{child1.id},John,Smith,2019-01-01,Male,"mother,grandfather",Other,Agency McAgence,Private insurance,Some comment,#{child1.created_at},#{child1.updated_at},#{family.id},"",true,false
#{child2.id},Jane,Smith,2018-01-01,Female,father,Hispanic,Agency McAgence,Private insurance,Some comment,#{child2.created_at},#{child2.updated_at},#{family.id},"",true,false
CSV
diff --git a/spec/requests/partners/family_requests_controller_spec.rb b/spec/requests/partners/family_requests_controller_spec.rb
index 04b17f75f2..a2d3a103de 100644
--- a/spec/requests/partners/family_requests_controller_spec.rb
+++ b/spec/requests/partners/family_requests_controller_spec.rb
@@ -32,9 +32,9 @@
describe 'POST #create' do
before do
# Set one child as deactivated and the other as active but
- # without a item_needed_diaperid
+ # without a needed items
children[0].update(active: false)
- children[1].update(item_needed_diaperid: nil)
+ children[1].needed_item_ids = []
end
subject { post partners_family_requests_path, params: params }
diff --git a/spec/system/partners/family_requests_system_spec.rb b/spec/system/partners/family_requests_system_spec.rb
index e1030f284a..8775eba7bc 100644
--- a/spec/system/partners/family_requests_system_spec.rb
+++ b/spec/system/partners/family_requests_system_spec.rb
@@ -10,13 +10,13 @@
end
describe "for children with different items, from different families" do
- let(:item_id) { Item.all.sample.id }
+ let(:item_ids) { Item.pluck(:id).sample(2).sort }
let!(:children) do
[
create(:partners_child, family: family),
- create(:partners_child, family: family, item_needed_diaperid: item_id),
- create(:partners_child, family: family, item_needed_diaperid: item_id),
- create(:partners_child, family: other_family, item_needed_diaperid: item_id),
+ create(:partners_child, family: family, needed_item_ids: item_ids),
+ create(:partners_child, family: family, needed_item_ids: item_ids),
+ create(:partners_child, family: other_family, needed_item_ids: item_ids),
create(:partners_child, family: other_family)
]
end
@@ -28,8 +28,16 @@
expect(page).to have_text("Request Details")
click_link "Your Previous Requests"
expect(page).to have_text("Request History")
- expect(Partners::ChildItemRequest.pluck(:child_id)).to match_array(children.pluck(:id))
- expect(Partners::ItemRequest.pluck(:item_id)).to match_array(children.pluck(:item_needed_diaperid).uniq)
+
+ expect(children[0].child_item_requests.size).to eq(1)
+ expect(children[1].child_item_requests.size).to eq(2)
+ expect(children[2].child_item_requests.size).to eq(2)
+ expect(children[3].child_item_requests.size).to eq(2)
+ expect(children[4].child_item_requests.size).to eq(1)
+ expect(children[1].child_item_requests.map(&:item_request).map(&:item_id).sort).to eq(item_ids)
+ expect(children[2].child_item_requests.map(&:item_request).map(&:item_id).sort).to eq(item_ids)
+ expect(children[3].child_item_requests.map(&:item_request).map(&:item_id).sort).to eq(item_ids)
+ expect(Partners::ItemRequest.pluck(:item_id)).to match_array(children.map(&:needed_item_ids).flatten.uniq)
end
end
|