Eigene Komponente: Fehler beim Speichern eines Eintrags im Backend

  • Hallo,

    ich habe ein kleines Problem beim Programmieren einer eigenen Komponente. Die Komponente soll dazu dienen eine Speiseplan für eine Schule zu erstellen.


    Kurz was zum Aufbau:

    - 3 Datenbanktabellen

    - 3 Listenansichten im Backend inkl. den entsprechenden Formularansichten für die Daten


    Jetzt zum Problem:

    Bin ich in einer Formularansicht und betätige den Button "speichern" werden die Formulardaten zwar korrekt in die entsprechende Datenbank geschrieben das Formular aber leer neu geladen. Normalerweise sollten aber die gerade gespeicherten Daten angezeigt werden.


    Ich vermute den Fehler im Model beim Laden der Formulardaten aus der Datenbank:

    Die Variable "$data" ist nach dem Speichern leer.


    Wie bekomme ich die gerade gespeicherten Daten in diese Variable?



    Mirko

  • Dann müssten beim apply die Daten im Form stehen bleiben, wenn du das übliche Schema anwendest.

    Bei save müsste es in die Übersicht zurück gehen.

    Eigentlich geht das automatisch wenn man nach dem üblichen Schema arbeitet.


    Es kommt jetzt daruf an was du anders machst. Kannst du mal mit einer der core Komponente vergleichen?

  • Hab gerade mal geschaut bei com_content und com_contact, sieht eh alles etwas anders aus, konnte aber nichts auffälliges finden.


    Welcher Teil der Komponente setzt eigentlich das

    $app->getUserState('com_meals.edit.ingredient.data', array());

    ?


    Hier mal die vollständige Model Datei für die Formularansicht:

  • Welcher Teil der Komponente setzt eigentlich das

    $app->getUserState('com_meals.edit.ingredient.data', array());

    ?

    Da werden Formulareingaben temporär gespeichert, wenn die Eingabe noch nicht fertig ist. Also z.B. wenn du was ins Formular eingetragen hast, aber ein Feld falsch oder nicht ausgefüllt hast. Dann wirst du ja wieder zum Formular zurückgeleitet und willst nicht wieder alles von vorn eingeben. Dafür ist das da. Wenn ich das richtig im Kopf habe, wird der im Controller befüllt.

    Ich würde übrigens noch überlegen, anstatt die save-Methode komplett in deinem Model zu machen, über die Methode des übergeordneten Models parent::save zu gehen, da da schon viele Sachen abgefangen werden.


    Zu deinem Problem: Stimmt denn der Redirect, d.h. wirst du nach dem Speichern auf die richtige Seite (mit der neuen ID in der URL) geleitet? Und was steht in der Variable $requested_id in loadFormData?

  • Ich war mal abwesend.

    Es ist etwas schwierig, aus Bruchstücken was zu erkennen Soweit ich sehe machst du sachen (delete, getItem) die eigentlich vom parent gemacht werden.

    Ich würde das loadFormData etwa so schreiben:


  • Zitat

    Zu deinem Problem: Stimmt denn der Redirect, d.h. wirst du nach dem Speichern auf die richtige Seite (mit der neuen ID in der URL) geleitet? Und was steht in der Variable $requested_id in loadFormData?

    Klicke ich in der Übersichtstabelle der View "ingredients" auf einen Eintrag bekomme ich mit $requested_id die Id des Eintrags. Speichere ich den Eintrag ist die $requested_id leer, bzw. 0. Und der Redirect gibt mir eine URL ohne Id aus (option=com_meals&view=ingredient&layout=edit).


    Kann es sein, dass das Problem bei JTable liegt?


    Die Komponente besitzt ja drei SQL Tabellen sozusagen für jeden View eine. Im "tables" Ordner liegt aber nur eine Datei "meals.php".


    Hier mal die Dateistruktur der Komponente (siehe Anhang).



    Mirko

  • Und der Redirect gibt mir eine URL ohne Id aus (option=com_meals&view=ingredient&layout=edit).

    Dann ist das das Problem. Hast du die save-Methode im Controller auch selbst eingerichtet oder benutzt du da die von FormController? In ersterem Fall müsstest du dir überlegen, woher du die ID des neu gespeicherten Datensatzes herbekommst, und diese an den Redirect anhängen. Wenn du die von FormController verwendest, sollte das dort schon drin sein, vorausgesetzt, das Model legt die ID im State ab. AdminModel macht das z.B. hier: https://github.com/joomla/joom…odel/AdminModel.php#L1302

    Spricht denn etwas dagegen, nach deiner Vorverarbeitung (json_encode etc) die Daten im Model über parent::save($data) zu speichern?

  • So habs mir mal soweit angeschaut und eine Frage dazu:


    Im Admin Model steht folgende Zeile:

    Code
    if (isset($table->$key)) {
        $this->setState($this->getName() . '.id', $table->$key);
    }

    Ich nehme mal an das $table->$key aus der Funktion ...

    Code
    public function getTable($type = 'meals', $prefix = 'MealsTable', $config = array()) {
        return JTable::getInstance($type, $prefix, $config);
    }

    ..gespeist wird?


    Wenn ja, würde er ja vermutlich – entsprechend der Funktion oben – auf die Tabelle #__meals_items zugreifen. Die währe aber nicht korrekt, sondern die Tabelle #__meals_ingredients.


    Sehe ich das richtig?

  • Zweite Sache parent::save():

    Ich hab jetzt im Model mal folgendes eingetragen – meinst du das?

    Code
    public function save($data) {
        $data['allergens'] = json_encode($data['allergens']);
        return parent::save($data);
    }


    Das funktioniert nur bedingt, da der Datensatz dann statt in #__meals_ingredients in die Haupttabelle #__meals_items gespeichert wird.

  • Ich habs!!!


    Folgendes musste ich anpassen:


    1. im Ordner "tables" eine ingredients.php anlegen.

    2. Model der ingredient.php anpassen

    3. Datenbank #__meals_ingredients die Spalte mit der Id von "ingredient_id" auf "id" ändern

    4. kleinere Anpassungen durch die Änderung der Id-Spalte in der Datenbank.


    Danke an alle für die Hilfestellungen! Das hat auf jeden Fall mein Verständnis für einige Abläufe verbessert.