Use form hash structure

The array format is generally fine, but to properly support checkboxes, we need this format with hash keys.
https://guides.rubyonrails.org/form_helpers.html#understanding-parameter-naming-conventions
This commit is contained in:
David Cook
2023-11-15 14:44:38 +11:00
parent 55cd8a6773
commit eccfe96a5b
4 changed files with 45 additions and 35 deletions

View File

@@ -167,18 +167,26 @@ class ProductsReflex < ApplicationReflex
# Form field names:
# '[products][0][id]' (hidden field)
# '[products][0][name]'
# '[products][0][variants_attributes][0][id]' (hidden field)
# '[products][0][variants_attributes][0][display_name]'
#
# Resulting in params:
# "products" => {
# "<i>" => {
# "0" => {
# "id" => "123"
# "name" => "Pommes",
# "variants_attributes" => {
# "0" => {
# "id" => "1234",
# "display_name" => "Large box",
# }
# }
# }
collection_hash = products_bulk_params[:products].each_with_index
.to_h { |p, i|
[i, p]
collection_hash = products_bulk_params[:products]
.transform_values { |product|
# Convert variants_attributes form hash to an array if present
product[:variants_attributes] &&= product[:variants_attributes].values
product
}.with_indifferent_access
Sets::ProductSet.new(collection_attributes: collection_hash)
end

View File

@@ -38,8 +38,8 @@
%th.align-left= t('admin.products_page.columns.tax_category')
%th.align-left= t('admin.products_page.columns.inherits_properties')
%th.align-right= t('admin.products_page.columns.actions')
- products.each do |product|
= form.fields_for("products", product, index: nil) do |product_form|
- products.each_with_index do |product, product_index|
= form.fields_for("products", product, index: product_index) do |product_form|
%tbody.relaxed{ 'data-record-id': product_form.object.id }
%tr
%td.field.align-left.header
@@ -70,8 +70,8 @@
= link_to t('admin.products_page.actions.edit'), edit_admin_product_path(product)
= link_to t('admin.products_page.actions.clone'), clone_admin_product_path(product)
- product.variants.each do |variant|
= form.fields_for("products][][variants_attributes][", variant, index: nil) do |variant_form|
- product.variants.each_with_index do |variant, variant_index|
= form.fields_for("products][#{product_index}][variants_attributes][", variant, variant_index:) do |variant_form|
%tr.condensed
%td.field
= variant_form.hidden_field :id

View File

@@ -39,14 +39,14 @@ describe ProductsReflex, type: :reflex, feature: :admin_style_v3 do
it "saves valid changes" do
params = {
# '[products][][name]'
"products" => [
{
# '[products][0][name]'
"products" => {
"0" => {
"id" => product_a.id.to_s,
"name" => "Pommes",
"sku" => "POM-00",
}
]
},
},
}
expect{
@@ -57,24 +57,27 @@ describe ProductsReflex, type: :reflex, feature: :admin_style_v3 do
end
it "saves valid changes to products and nested variants" do
# Form field names:
# '[products][0][id]' (hidden field)
# '[products][0][name]'
# '[products][0][variants_attributes][0][id]' (hidden field)
# '[products][0][variants_attributes][0][display_name]'
params = {
# '[products][][name]'
# '[products][][variants_attributes][][display_name]'
"products" => [
{
"products" => {
"0" => {
"id" => product_a.id.to_s,
"name" => "Pommes",
"variants_attributes" => [
{
"variants_attributes" => {
"0" => {
"id" => variant_a1.id.to_s,
"display_name" => "Large box",
"sku" => "POM-01",
"price" => "10.25",
"on_hand" => "6",
}
],
}
]
},
},
},
},
}
expect{
@@ -91,15 +94,15 @@ describe ProductsReflex, type: :reflex, feature: :admin_style_v3 do
describe "sorting" do
let(:params) {
{
"products" => [
{
"products" => {
"0" => {
"id" => product_a.id.to_s,
"name" => "Pommes",
},
{
"1" => {
"id" => product_b.id.to_s,
},
]
},
}
}
subject{ run_reflex(:bulk_update, params:) }
@@ -115,20 +118,20 @@ describe ProductsReflex, type: :reflex, feature: :admin_style_v3 do
describe "error messages" do
it "summarises error messages" do
params = {
"products" => [
{
"products" => {
"0" => {
"id" => product_a.id.to_s,
"name" => "Pommes",
},
{
"1" => {
"id" => product_b.id.to_s,
"name" => "", # Name can't be blank
},
{
"2" => {
"id" => product_c.id.to_s,
"name" => "", # Name can't be blank
},
]
},
}
reflex = run_reflex(:bulk_update, params:)

View File

@@ -225,8 +225,7 @@ describe 'As an admin, I can see the new product page', feature: :admin_style_v3
.and change{ variant_a1.sku }.to("POM-01")
.and change{ variant_a1.price }.to(10.25)
.and change{ variant_a1.on_hand }.to(6)
pending "Array parameters do not play well with the check_box helper."
# .and change{ variant_a1.on_demand }.to(true)
.and change{ variant_a1.on_demand }.to(true)
within row_containing_name("Pommes") do
expect(page).to have_field "Name", with: "Pommes"