The attribute record
Every attribute is aProductAttribute record (id prefix pattr) with a name, a type, and a few flags. Its selectable choices are separate ProductAttributeValue records (id prefix pattrval) that belong to it and are deleted with it.
src/scripts/seed-attributes.ts
single_select attribute with two values. Because no handle is passed, the module derives material from the name.
The five types
Thetype field takes one of the AttributeType enum values. Each type stores what a product holds in a different way:
Only a
multi_select attribute can be a variant axis. The other four types describe a product but never shape its variants.
How values link to products
A product doesn’t store attribute data on itself. Instead, each value it holds is linked to it through the product to value pivot link, and the shape of that link depends on the type:- Select types: the product links to existing values you pick by id
- Text and unit: attaching creates a new
ProductAttributeValuenamed after the entered content, for example"400", and links it - Toggle: the product links to the seeded
"true"or"false"value, and no new value is ever created
unit stores the number as the value’s name string. The attribute has no separate unit-of-measure field, so put the unit in the attribute name, for example “Weight (kg)”.Rules the module enforces
The Product Attribute service adds a few rules on top of the generated CRUD methods:- Type is fixed:
updateProductAttributesthrows when you try to change thetypeof an existing attribute - Handles are derived: a global attribute without a
handlegets one from its name, and global select values get one from theirs - Handles are unique: attribute handles are unique across the catalog, and value handles are unique per attribute
- Toggle values are seeded: creating a
toggleattribute adds itstrue(rank 0) andfalse(rank 1) values