Skip to content

Commit 9b0635c

Browse files
committed
fix: set AttributeRef in ComboBox association binding
setAssociationRef only set EntityRef but not AttributeRef, causing the association path to be lost in the BSON output. Also fixed extractCustomWidgetAttribute to look up specific property keys (attributeAssociation, attributeEnumeration) instead of returning the first AttributeRef found, which could match CaptionAttribute.
1 parent 8c987d3 commit 9b0635c

2 files changed

Lines changed: 20 additions & 27 deletions

File tree

mdl/executor/cmd_pages_builder_input.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,14 +172,24 @@ func setDataSource(val bson.D, ds pages.DataSource) bson.D {
172172
return result
173173
}
174174

175-
// setAssociationRef sets the EntityRef field in a WidgetValue for an association binding
176-
// on a pluggable widget. Uses DomainModels$IndirectEntityRef with a Steps array containing
175+
// setAssociationRef sets both the AttributeRef and EntityRef fields in a WidgetValue
176+
// for an association binding on a pluggable widget.
177+
// AttributeRef stores the association qualified name (e.g., "Module.Order_Customer").
178+
// EntityRef uses DomainModels$IndirectEntityRef with a Steps array containing
177179
// a DomainModels$EntityRefStep that specifies the association and destination entity.
178-
// MxBuild requires the EntityRef to resolve the association target (CE0642, CE8812).
180+
// MxBuild requires both: association path in AttributeRef (CE8812) and
181+
// target entity in EntityRef (CE0642).
179182
func setAssociationRef(val bson.D, assocPath string, entityName string) bson.D {
180183
result := make(bson.D, 0, len(val))
181184
for _, elem := range val {
182-
if elem.Key == "EntityRef" && entityName != "" {
185+
if elem.Key == "AttributeRef" && assocPath != "" {
186+
result = append(result, bson.E{Key: "AttributeRef", Value: bson.D{
187+
{Key: "$ID", Value: mpr.IDToBsonBinary(mpr.GenerateID())},
188+
{Key: "$Type", Value: "DomainModels$AttributeRef"},
189+
{Key: "Attribute", Value: assocPath},
190+
{Key: "EntityRef", Value: nil},
191+
}})
192+
} else if elem.Key == "EntityRef" && entityName != "" {
183193
result = append(result, bson.E{Key: "EntityRef", Value: bson.D{
184194
{Key: "$ID", Value: mpr.IDToBsonBinary(mpr.GenerateID())},
185195
{Key: "$Type", Value: "DomainModels$IndirectEntityRef"},

mdl/executor/cmd_pages_describe_pluggable.go

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,13 @@ import (
77
)
88

99
// extractCustomWidgetAttribute extracts the attribute from a CustomWidget (e.g., ComboBox).
10+
// Specifically looks for attributeAssociation or attributeEnumeration properties by key,
11+
// avoiding false matches from other properties that also have AttributeRef (e.g., CaptionAttribute).
1012
func (e *Executor) extractCustomWidgetAttribute(w map[string]any) string {
11-
obj, ok := w["Object"].(map[string]any)
12-
if !ok {
13-
return ""
14-
}
15-
16-
// Search through properties for attributeEnumeration or attributeAssociation
17-
props := getBsonArrayElements(obj["Properties"])
18-
for _, prop := range props {
19-
propMap, ok := prop.(map[string]any)
20-
if !ok {
21-
continue
22-
}
23-
value, ok := propMap["Value"].(map[string]any)
24-
if !ok {
25-
continue
26-
}
27-
// Check for AttributeRef
28-
attrRef, ok := value["AttributeRef"].(map[string]any)
29-
if !ok {
30-
continue
31-
}
32-
if attr, ok := attrRef["Attribute"].(string); ok && attr != "" {
33-
return shortAttributeName(attr)
13+
// Try association attribute first, then enumeration attribute
14+
for _, key := range []string{"attributeAssociation", "attributeEnumeration"} {
15+
if attr := e.extractCustomWidgetPropertyAttributeRef(w, key); attr != "" {
16+
return attr
3417
}
3518
}
3619
return ""

0 commit comments

Comments
 (0)