GORM für Einsteiger

Hier finden sich Fragen und Ergänzung zur Dokumentation. // All questions and discussions about the documentation.
Antworten
Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: GORM für Einsteiger

Beitrag von ma2604121 » 05.09.2011, 18:54:21

Wiki ist ergänzt.

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: GORM für Einsteiger

Beitrag von ma2604121 » 05.09.2011, 22:14:28

Kann man dem GORM auch irgendwelche Sortierkriterien mitgeben?

Ich vermute so:

Code: Alles auswählen

$select = 'SELECT * FROM ent_user WHERE UserID = \'1\';';
 $User = $ORM->loadObjectByTextStatement('User',$select); 

Megger
Beiträge: 1233
Registriert: 04.11.2008, 10:57:37

Re: GORM für Einsteiger

Beitrag von Megger » 05.09.2011, 22:30:28

Du kannst sogut wie alles über Criterion Objekte erledigen!

Code: Alles auswählen

$crit = new GenericCriterionObject();
$crit->addOrderIndicator('Test'); //Damit wird es ASC sortiert, da der zweite Parameter standardmäßig so eingestellt ist
 
Tutorial: Browsergame mit dem APF (Die ersten Parts handeln von Installation und Inbetriebnahme des APFs, deswegen sicherlich auch für alle Nicht-Browsergame-Programmierer interessant)

APF-Version
  • Entwicklung: 2.0
  • Produktiv: 1.15

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: GORM für Einsteiger

Beitrag von ma2604121 » 05.09.2011, 22:36:38

Klasse!
Ich hatte schon immer den Eindruck, dass es sich lohnen könnte, sich mit dem GORM zu beschäftigen. Mein Eindruck bestätigt sich immer mehr... :)

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: GORM für Einsteiger

Beitrag von ma2604121 » 05.09.2011, 22:49:37

Nun zum letzten Teil:
Der verknüpften Ausgabe von Autor und Bücher.

Das Template soll wie folgt aussehen:

Code: Alles auswählen

<@controller namespace="books::pres::controller" file="AuthorBooksListController" class="AuthorBooksListController" @>
<h2>List of all authors and their books</h2>
<table>
    <tr>
    <th>Author</th>
    <th>Title</th>
    <th>Price</th>
    <th>Date</th>
    </tr>
    <html:placeholder name="DisplayAll" />
</table>

<html:template name="DisplayAll">
    <tr>
    <td><template:placeholder name="AuthorName" /></td>
    <td><template:placeholder name="Title" /></td>
    <td><template:placeholder name="Price" /></td>
    <td><template:placeholder name="CreateDate" /></td>
    </tr>
</html:template> 
Und wie bringe ich in diesem Fall dem GORM bei, die Daten entsprechend zu laden? Ich würde hier die Methode loadRelatedObjects() vermuten?

Benutzeravatar
dr.e.
Administrator
Beiträge: 4533
Registriert: 04.11.2007, 16:13:53

Re: GORM für Einsteiger

Beitrag von dr.e. » 05.09.2011, 23:02:34

Die Daten-Objekt-Definition sieht doch eine n:m-Beziehung zwischen Autor und Buch vor. Daher ist es etwas schwierig, eine eindimensionale Darstellung zu haben, da sich entweder Autoren oder Titel wiederholen. Sofern du eine Wiederholung von Autoren akzeptierst, so kannst du dir die Daten wie folgt zusammenstellen:

Code: Alles auswählen

$buffer = '';
$tmpl = &$this->getTemplate('DisplayAll');
$books = $orm->loadObjectListByTextStatement('SELECT * FROM ent_book');
foreach($books as $book) {
   $author = $orm->loadRelatedObject($book, 'Author2Book');
   $tmpl->setPlaceHolder('AuthorName', $author->getProperty('Name'));
   $tmpl->setPlaceHolder('Title', $book->getProperty('Title'));
   ...
   $buffer .= $tmpl->transformTemplate();
}
$this->setPlaceHolder('DisplayAll', $buffer); 
(Code ist frei getippt, kann also durchaus Fehler enthalten!)
Viele Grüße,
Christian

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: GORM für Einsteiger

Beitrag von ma2604121 » 05.09.2011, 23:05:07

dr.e. hat geschrieben:Sofern du eine Wiederholung von Autoren akzeptierst, so kannst du dir die Daten wie folgt zusammenstellen
Das passt schon. Mir geht es nur um das Verständnis. Da darf gerne eine Wiederholung der Autoren stattfinden.

Benutzeravatar
dr.e.
Administrator
Beiträge: 4533
Registriert: 04.11.2007, 16:13:53

Re: GORM für Einsteiger

Beitrag von dr.e. » 05.09.2011, 23:11:48

OK. Alternativ kannst du natürlich die Liste der Bücher auch per loadObjectListByCriterion() bewerkstelligen um die Bücher z.B. nach dem Alphabet zu sortieren.
Viele Grüße,
Christian

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: GORM für Einsteiger

Beitrag von ma2604121 » 05.09.2011, 23:15:54

Code: Alles auswählen

    foreach ($BooksList as $Book){

        $Author = $orm->loadRelatedObjects($Book, 'Author2Book');

        $template->setPlaceHolder('AuthorName', $Author->getProperty('Author'));
        $template->setPlaceHolder('Title', $Book->getProperty('Title'));
        $template->setPlaceHolder('Price', $Book->getProperty('Price'));
        $template->setPlaceHolder('CreateDate', $Book->getProperty('CreationTimestamp'));
        $buffer .= $template->transformTemplate();
    } 
Führt zu:

Code: Alles auswählen

Fatal error: Call to a member function getProperty() on a non-object in /var/www/apf_114_demo/apps/books/pres/controller/AuthorBooksListController.php on line 26 

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: GORM für Einsteiger

Beitrag von ma2604121 » 05.09.2011, 23:20:30

Tippfehler...

Passt alles!!

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: GORM für Einsteiger

Beitrag von ma2604121 » 06.09.2011, 00:31:43

Habe jetzt auf die Schnelle nichts gefunden, aber:

Ist der GORM auch in der Lage, alle in einer Beziehung stehenden Verbindungen zu löschen? Also hier in diesem Fall: Wenn ich einen Autor lösche, ist es dann auch möglich, dass der GORM alle diesem zugeordneten Bücher löscht?

Benutzeravatar
dr.e.
Administrator
Beiträge: 4533
Registriert: 04.11.2007, 16:13:53

Re: GORM für Einsteiger

Beitrag von dr.e. » 06.09.2011, 07:50:00

Hi,

jep, das kann der GORM. Ist ein Objekt beispielsweise einmal komponiert und zweimal assoziiert, werden beim Löschen des Objektes 3 Beziehungen mit gelöscht. Es ist allerdings aus Konsistenzgründen nur erlaubt, Objekte zu löschen, die keine weiteren komponieren. Das ist in deinem Fall aber nicht relevant.

Ein Hinweis in der Doku dazu wäre aber sicher nicht schlecht. :roll: Vielleicht kannst du das ja auf die Wiki-Seite übernehmen. Danke! :)
Viele Grüße,
Christian

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: GORM für Einsteiger

Beitrag von ma2604121 » 06.09.2011, 09:32:08

Das klingt gut.

Aber offensichtlich bin ich nicht in der Lage die entsprechende Methode zu finden:

http://adventure-php-framework.org/Seit ... -OR-Mapper
Hier steht zwar
Für diese Aufgaben stehen eine Reihe von API-Funktionen zur Verfügung, die das Laden, Manipulieren und Löschen von definierten Objekten in der Datenbank abbilden.
Aber auf der restlichen Seite lese ich nichts mehr von irgendeiner Methode, mit der das Löschen gehen würde.

Ich habe mich mal durch den UserManager gehangelt und bin dort auf deleteObject() gestoßen. HIerbei dürfte es sich um die gesuchte Methode handeln, wenn ich den Code richtig lese?

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: GORM für Einsteiger

Beitrag von ma2604121 » 06.09.2011, 09:55:14

Also das Löschen eines Buches ist kein Problem:

Code: Alles auswählen

<@controller namespace="books::pres::controller" file="DeleteBookController" class="DeleteBookController" @>
<core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />
<h2>Delete a book</h2>
<html:form name="DeleteBook">
    <label for="Book">Book : </label>
    <form:select name="Books"/><br/>
    <form:button name="SubmitBook" value="Delete book"/>
</html:form>

<html:template name="BooksList">
    <select:option value="<template:placeholder name="ID"/>"><template:placeholder name="Title"/></select:option>
</html:template> 

Code: Alles auswählen

<?php
import('tools::link','FrontcontrollerLinkHandler');
import('modules::genericormapper::data','GenericDomainObject');
import('tools::http', 'HeaderManager');
class DeleteBookController extends base_controller{
    public function  transformContent() {
    $form = &$this->getForm('DeleteBook');
    $orm = $this->getMapper();
    $Crit = new GenericCriterionObject();
    $Crit->addPropertyIndicator('Title','%');
    $BooksList = $orm->loadObjectListByCriterion('Books',$Crit);
    $selectOption = &$form->getFormElementByName('Books');
    foreach ($BooksList as $Book){
        $selectOption->addOption($Book->getProperty('Title'), $Book->getProperty('BooksID'));
    }
    if ($form->isSent() && $form->isValid()){
        $Book = new GenericDomainObject('Books');
        $Book->setProperty('BooksID',$form->getFormElementByName('Books')->getSelectedOption()->getValue());
        $orm = $this->getMapper();
        $orm->deleteObject($Book);
        HeaderManager::forward('?page=booklist');
    }
    else{
        $form->transformOnPlace();
    }
    }

    private function getMapper(){
    $ormFact = &$this->getServiceObject('modules::genericormapper::data', 'GenericORMapperFactory');
    return $ormFact->getGenericORMapper('modules::gorm', 'books', 'books');
    }
}
?>
Wenn ich nun aber einen Autor und seine Bücher löschen möchte

Code: Alles auswählen

<@controller namespace="books::pres::controller" file="DeleteAuthorController" class="DeleteAuthorController" @>
<core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />
<h2>Delete an autor and assigned books</h2>
<html:form name="DeleteAuthor">
    <label for="Author">Author : </label>
    <form:select name="Author"/><br/>
    <form:button name="SubmitBook" value="Delete author and assigned books"/>
</html:form>

<html:template name="AuthorList">
    <select:option value="<template:placeholder name="ID"/>"><template:placeholder name="AuthorName"/></select:option>
</html:template> 

Code: Alles auswählen

<?php
import('tools::link','FrontcontrollerLinkHandler');
import('modules::genericormapper::data','GenericDomainObject');
import('tools::http', 'HeaderManager');
class DeleteAuthorController extends base_controller{
    public function  transformContent() {
    $form = &$this->getForm('DeleteAuthor');
    $orm = $this->getMapper();
    $Crit = new GenericCriterionObject();
    $Crit->addPropertyIndicator('Author','%');
    $AuthorsList = $orm->loadObjectListByCriterion('Authors',$Crit);
    $selectOption = &$form->getFormElementByName('Author');
    foreach ($AuthorsList as $Author){
        $selectOption->addOption($Author->getProperty('Author'), $Author->getProperty('AuthorsID'));
    }
    if ($form->isSent() && $form->isValid()){
        $Author = new GenericDomainObject('Authors');
        $Author->setProperty('AuthorsID',$form->getFormElementByName('Author')->getSelectedOption()->getValue());
        $orm = $this->getMapper();
        $orm->deleteObject($Author);
        HeaderManager::forward('?page=authorbookslist');
    }
    else{
        $form->transformOnPlace();
    }
    }

    private function getMapper(){
    $ormFact = &$this->getServiceObject('modules::genericormapper::data', 'GenericORMapperFactory');
    return $ormFact->getGenericORMapper('modules::gorm', 'books', 'books');
    }
}
?>
Erhalte ich den Fehler:

Code: Alles auswählen

	[GenericORRelationMapper::deleteObject()] Domain object "Authors" with id "26" cannot be deleted, because it still has composed child objects! 
Also müssen noch irgendwie die verknüpften Objekte gelöscht werden. Wie stelle ich das an?
Zuletzt geändert von ma2604121 am 06.09.2011, 09:59:04, insgesamt 1-mal geändert.

Benutzeravatar
ma2604121
Beiträge: 349
Registriert: 24.01.2011, 23:42:18

Re: GORM für Einsteiger

Beitrag von ma2604121 » 06.09.2011, 09:58:04

Ich habe es wie folgt gelöst:

Code: Alles auswählen

if ($form->isSent() && $form->isValid()){
        $Author = new GenericDomainObject('Authors');
        $Author->setProperty('AuthorsID',$form->getFormElementByName('Author')->getSelectedOption()->getValue());
        $BooksList= $orm->loadRelatedObjects($Author, 'Author2Book');
        foreach ($BooksList as $Book){
        $orm = $this->getMapper();
        $orm->deleteObject($Book);
        }
        $orm = $this->getMapper();
        $orm->deleteObject($Author);
        HeaderManager::forward('?page=authorbookslist');
    } 
Oder gibt es eine bessere bzw. elegantere Lösung?

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast