Hallo, ich habe ein Plugin mit zwei eigenen Entities, parent und child, die über eine OneToMany-Association miteinander verbunden sind. Für ein child ist die Angabe eines parent obligatorisch.
Über ein eigenes Admin-Modul möchte ich nun zu einem vorgegebenen _parent _neue children erstellen können.
Problem: Bei meinem Code, der an die Dokumentation angelehnt ist, kommt es zum Error-500, offenbar weil im API-Call zum Speichern die ID vom gesetzten child.parent überhaupt nicht übermittelt wird (wie über die Entwicklerkonsole ersichtlich ist).
Zum Beispiel ist das parent-Objekt im Vue-Code als _this.parent _verfügbar. Nun will ich ein neues child namens nc erstellen, bei diesem nc.parent = this.parent setzen, und dann _nc _abspeichern. Das ergibt jedoch einen 500er Fehler:
const cr = this.repositoryFactory.create('etoile_child');
const nc = cr.create(Shopware.Context.api);
nc.infotext = "Hello world"; // Dies wird korrekt per JSON an API übertragen,
nc.parent = this.parent; // dies nicht.
childrenRepository.save(nc, Shopware.Content.api) // --> Gibt Error 500, wahrscheinlich eben weil obligatorische parent.id im Payload fehlt.
Aber eigentlich sollte das doch funktionieren, oder? Liegt der Hund dann eher irgendwo im PHP-Teil meines Codes begraben?
Hier noch zum besseren Verständnis der Gesamt-Code meiner Datei page/etoile-parent-detail/index.js.
// Interessanter Teil sind die Funktionen getParent und onClickSave unten.
import template from './etoile-parent-detail.html.twig';
const { Component, Mixin } = Shopware;
const Criteria = Shopware.Data.Criteria;
Component.register('etoile-parent-detail', {
template,
inject: [
'repositoryFactory'
],
mixins: [
Mixin.getByName('notification')
],
metaInfo() {
return {
title: this.$createTitle()
};
},
data() {
console.log("data");
return {
parent: null,
isLoading: false,
processSuccess: false,
repository: null
};
},
computed: {
columns() {
// ...
}
},
created() {
console.log("created");
this.repository = this.repositoryFactory.create('etoile_parent');
this.getParent();
},
methods: {
getParent() {
// Diese Funktion lädt für this.parent die entsprechende Entity aus der Datenbank.
this.repository
.get(this.$route.params.id, Shopware.Context.api)
.then((entity) => {
this.parent = entity;
console.log(Shopware);
});
},
onClickSave() {
console.log("onClickSave of detail")
// Dieser Block sollen dazu dienen, ein neues child zu erstellen, ihm this.parent als parent zuzuweisen, und es dann abzuspeichern (bei jedem Klick auf 'Save', dies aber nur zu Testzwecken).
const cr = this.repositoryFactory.create('etoile_child');
const nc = cr.create(Shopware.Context.api);
nc.infotext = "Hello world"; // Dieses Feld wird korrekt an die API übertragen
nc.parent = this.parent; // Dieses "Feld" nicht. Auch wenn nc.parentId = this.parent.id gesetzt wird, ist es nicht besser.
cr.save(nc, Shopware.Context.api); // Ergibt besagten 500-Fehler.
console.log(this.parent.id); // Gibt korrekte ID vom parent aus
console.log(child.parent.id); // Gibt ebenfalls dasselbe aus.
// Von hier an entspricht der Code dem Bundle-Example, hat mit child nichts mehr zu tun, und läuft problemlos, d.h. er speichert this.parent korrekt in der DB ab.
this.isLoading = true;
this.repository
.save(this.parent, Shopware.Context.api)
.then(() => {
this.getParent();
this.isLoading = false;
this.processSuccess = true;
}).catch((exception) => {
this.isLoading = false;
this.createNotificationError({
title: this.$t('etoile-parent.detail.errorTitle'),
message: exception
});
});
},
saveFinish() {
console.log("saveFinish");
this.processSuccess = false;
}
}
});
(Nebenbemerkung: Mit CMS-Modulen hat das alles an dieser Stelle nicht zu tun; dies erwähne ich nur, weil es bei einer anderen Frage von mir um solche ging.)