[solved] [newbie] Anzeige von Daten aus mySQL-DB (verschiedene Tabellen)

Auf ein neues…

Die nächste doofe Frage, auf die ich keine richtige Antwort im Handbuch oder im Forum gefunden habe:

Hier die Problemstellung:

Ich habe mit GII die Models und Views für tbl_gallery, tbl_pictures, etc. erstellt, diese funktionieren auch an sich.

Jetzt möchte ich, wenn ich mir einen Datensatz von tbl_gallery ansehe, darunter alle Datensätze aus der Tabelle tbl_pictures haben, die die selbe ID (FK=tbl_pictures.gallery), wie der angezeigte Datensatz (Übergabe der Variable mit GET-Funktion) hat.

Hier einmal die DB-Struktur:


-- --------------------------------------------------------


--

-- Tabellenstruktur für Tabelle 'tbl_gallery'

--


CREATE TABLE tbl_gallery (

  id int(11) NOT NULL auto_increment,

  portfolio tinyint(1) NOT NULL,

  title varchar(100) default NULL,

  description varchar(255) default NULL,

  `date` date default NULL,

  rating int(11) default NULL,

  location_id int(11) default NULL,

  PRIMARY KEY  (id),

  KEY location_id (location_id)

) ENGINE=InnoDB  DEFAULT CHARSET=latin1;


-- --------------------------------------------------------


--

-- Tabellenstruktur für Tabelle 'tbl_location'

--


CREATE TABLE tbl_location (

  id int(11) NOT NULL auto_increment,

  `name` varchar(50) NOT NULL,

  adress varchar(100) NOT NULL,

  postalcode varchar(5) NOT NULL,

  town varchar(50) NOT NULL,

  web varchar(50) NOT NULL,

  geo varchar(19) NOT NULL,

  PRIMARY KEY  (id)

) ENGINE=InnoDB  DEFAULT CHARSET=latin1;


-- --------------------------------------------------------


--

-- Tabellenstruktur für Tabelle 'tbl_pictures'

--


CREATE TABLE tbl_pictures (

  id int(11) NOT NULL auto_increment,

  picturenumber int(11) NOT NULL,

  gallery int(11) NOT NULL,

  portfolio tinyint(1) NOT NULL,

  PRIMARY KEY  (id),

  KEY gallery (gallery)

) ENGINE=InnoDB  DEFAULT CHARSET=latin1;


-- --------------------------------------------------------


--

-- Tabellenstruktur für Tabelle 'tbl_portfolio'

--


CREATE TABLE tbl_portfolio (

  id int(11) NOT NULL auto_increment,

  title varchar(30) NOT NULL,

  description varchar(150) NOT NULL,

  PRIMARY KEY  (id)

) ENGINE=InnoDB DEFAULT CHARSET=latin1;


-- --------------------------------------------------------


--

-- Tabellenstruktur für Tabelle 'tbl_user'

--


CREATE TABLE tbl_user (

  id int(11) NOT NULL auto_increment,

  username varchar(128) NOT NULL,

  `PASSWORD` varchar(128) NOT NULL,

  firstname varchar(20) NOT NULL,

  lastname varchar(50) NOT NULL,

  email varchar(128) NOT NULL,

  phone varchar(20) NOT NULL,

  town varchar(50) NOT NULL,

  PRIMARY KEY  (id)

) ENGINE=InnoDB  DEFAULT CHARSET=latin1;


--

-- Constraints der exportierten Tabellen

--


--

-- Constraints der Tabelle `tbl_gallery`

--

ALTER TABLE `tbl_gallery`

  ADD CONSTRAINT tbl_gallery_ibfk_1 FOREIGN KEY (location_id) REFERENCES tbl_location (id);


--

-- Constraints der Tabelle `tbl_pictures`

--

ALTER TABLE `tbl_pictures`

  ADD CONSTRAINT tbl_pictures_ibfk_1 FOREIGN KEY (gallery) REFERENCES tbl_gallery (id);

Hier noch ein Screenshot, wie ich mir das vorstelle (Layout wird ja eh noch geändert) ;)

678

gallery.jpg

Schon einmal vielen Dank! :D

Wo genau liegt das Problem? Hier kurz, was zu tun ist. Frag nach, wenn das zu kurz ist :) :

  1. Model für Pictures anlegen (falls noch nicht geschehen)

  2. Relation in Gallery-Model auf Pictures definieren (self::HAS_MANY…)

  3. Im Controller, an der Stelle wo der Galleryrecord geladen wird ein ->with(‘Pictures’) einfügen

  4. Im View der Gallery ein foreach($model->Pictures as $picture) machen und Pictures rendern

  5. Sich über die Ausgabe freuen

Details zu jedem Punkt findest du auch im Guide.

Dann war ich ja schon einmal auf dem richtigen Weg! ;)

Mir hat nur der Zusammenhang in der Dokumentation gefehlt, zum Glück gibt es dieses Forum! :D

/protected/models/Gallery.php:




 55     /**

 56      * @return array relational rules.

 57      */

 58     public function relations()

 59     {

 60         // NOTE: you may need to adjust the relation name and the related

 61         // class name for the relations automatically generated below.

 62         return array(

 63             'location' => array(self::BELONGS_TO, 'TblLocation', 'location_id'),

 64             'pictures' => array(self::HAS_MANY, 'TblPictures', 'gallery'),

 65         );

 66     }



/protected/controllers/GalleryController.php




152     /**

153      * Returns the data model based on the primary key given in the GET variable.

154      * If the data model is not found, an HTTP exception will be raised.

155      */

156     public function loadModel()

157     {

158         if($this->_model===null)

159         {

160             if(isset($_GET['id']))

161                 $this->_model=Gallery::model()->with('Pictures')->findbyPk($_GET['id']);

162             if($this->_model===null)

163                 throw new CHttpException(404,'The requested page does not exist.');

164         }

165         return $this->_model;

166     }



Die Ausgabe mit Stack-Trace:




CDbException


Description

Relation "Pictures" is not defined in active record class "Gallery".


Source File

/home/pocra/yii/db/ar/CActiveFinder.php(253)

00241: 

00242:             // named scope

00243:             if(($pos=strpos($with,':'))!==false)

00244:             {

00245:                 $scopes=explode(':',substr($with,$pos+1));

00246:                 $with=substr($with,0,$pos);

00247:             }

00248: 

00249:             if(isset($parent->children[$with]))

00250:                 return $parent->children[$with];

00251: 

00252:             if(($relation=$parent->model->getActiveRelation($with))===null)

00253:                 throw new CDbException(Yii::t('yii','Relation "{name}" is not defined in active record class "{class}".',

00254:                     array('{class}'=>get_class($parent->model), '{name}'=>$with)));

00255: 

00256:             $relation=clone $relation;

00257:             $model=CActiveRecord::model($relation->className);

00258:             if(($scope=$model->defaultScope())!==array())

00259:                 $relation->mergeWith($scope);

00260:             if(!empty($scopes))

00261:             {

00262:                 $scs=$model->scopes();

00263:                 foreach($scopes as $scope)

00264:                 {

00265:                     if(isset($scs[$scope]))


Stack Trace

#0 /home/pocra/yii/db/ar/CActiveFinder.php(292): CActiveFinder->buildJoinTree(Object(CJoinElement), 'Pictures')

#1 /home/pocra/yii/db/ar/CActiveFinder.php(51): CActiveFinder->buildJoinTree(Object(CJoinElement), Array)

#2 /home/pocra/yii/db/ar/CActiveRecord.php(1430): CActiveFinder->__construct(Object(Gallery), Array)

#3 /home/pocra/domains/******/public_html/protected/controllers/GalleryController.php(161): CActiveRecord->with('Pictures')

#4 /home/pocra/domains/******/public_html/protected/controllers/GalleryController.php(58): GalleryController->loadModel()

#5 /home/pocra/yii/web/actions/CInlineAction.php(32): GalleryController->actionView()

#6 /home/pocra/yii/web/CController.php(300): CInlineAction->run()

#7 /home/pocra/yii/web/filters/CFilterChain.php(129): CController->runAction(Object(CInlineAction))

#8 /home/pocra/yii/web/filters/CFilter.php(41): CFilterChain->run()

#9 /home/pocra/yii/web/CController.php(999): CFilter->filter(Object(CFilterChain))

#10 /home/pocra/yii/web/filters/CInlineFilter.php(59): CController->filterAccessControl(Object(CFilterChain))

#11 /home/pocra/yii/web/filters/CFilterChain.php(126): CInlineFilter->filter(Object(CFilterChain))

#12 /home/pocra/yii/web/CController.php(283): CFilterChain->run()

#13 /home/pocra/yii/web/CController.php(257): CController->runActionWithFilters(Object(CInlineAction), Array)

#14 /home/pocra/yii/web/CWebApplication.php(320): CController->run('view')

#15 /home/pocra/yii/web/CWebApplication.php(120): CWebApplication->runController('gallery/view')

#16 /home/pocra/yii/base/CApplication.php(135): CWebApplication->processRequest()

#17 /home/pocra/domains/******/public_html/index.php(12): CApplication->run()

#18 {main}



Schreibweise ist entscheidend: Die Relation heißt ‘pictures’ (klein geschrieben).

Okay, Leichtsinnsfehler! ;)

Im View…das heißt unter /protected/views/Gallery/view.php?




  1 <?php

  2 $this->breadcrumbs=array(

  3     'Galleries'=>array('index'),

  4     $model->title,

  5 );

  6 

  7 $this->menu=array(

  8     array('label'=>'List Gallery', 'url'=>array('index')),

  9     array('label'=>'Create Gallery', 'url'=>array('create')),

 10     array('label'=>'Update Gallery', 'url'=>array('update', 'id'=>$model->id)),

 11     array('label'=>'Delete Gallery', 'url'=>'#', 'linkOptions'=>array('submit'=>array('delete','id'=>$model->id),'confirm'=>'Are you sure you want to delete this item?')),

 12     array('label'=>'Manage Gallery', 'url'=>array('admin')),

 13 );

 14 ?>

 15 

 16 <h1>View Gallery #<?php echo $model->id; ?></h1>

 17 

 18 <?php $this->widget('zii.widgets.CDetailView', array(

 19     'data'=>$model,

 20     'attributes'=>array(

 21         'id',

 22         'portfolio',

 23         'title',

 24         'description',

 25         'date',

 26         'rating',

 27         'location_id',

 28     ),

 29 ));

 30 ?>



Wo dort?

Ich glaub, ich muss noch echt viel lernen! :wink:

Hmm, wir müssen jetzt aber nicht gemeinsam erarbeiten, wie deine Seite aussehen soll, oder? ;)

Ganz ohne Nachdenken gehts halt auch mit Yii nicht. D.h. überleg dir, auf welcher Seite du die Pictures ausgeben willst und wie das dazu nötige HTML aussehen muss. view.php ist für den Start sicher in Ordnung. Fang simpel an, also z.B. gib erst mal die Picture-IDs aus. Wenn das klappt, hangel dich weiter zu nem <img> Tag, etc. je nachdem wie dein Layout halt aussehen soll.

Erst wenn du diese Basics mal etwas durchprobiert hast, würd ich mich an komplexere Komponenten wie CListView oder sogar CGridView wagen, die hier hilfreich sein könnten.

Übrigens noch ein Wort zu den CRUD:

Der generierte Code ist mehr als Beispiel zu sehen, wie man das machen kann - d.h. versuch eher mal zu verstehen, was dort passiert. In einem "richtigen" Projekt wirst du meist deinen eigenen Controller anlegen, der genau die Actions bietet, die du halt so brauchst. Darum ist es auch schwierig zu sagen "wo etwas hin muss" - das ist eher fast schon eine Geschmacksfrage.

Nein, nein das müssen wir nicht, da hab ich recht genaue Vorstellungen…nur die eigentlich Basics mit Yii fehlen teilweise noch! ;)

Tja, mit dem anzeigen der ID scheitert es gerade schon, wenn ich das hab, wird der Rest ziemlich leicht, dann kann ich dann auch für den Rest ableiten und auch auf andere Seiten anwenden! ;)

Ja, das mit CRUD glaube ich, wenn ich die ersten Sachen auf Basis von "Produktiv-Daten" (keine Angst, Kopie der DB XD), mit dem Standard mir anzeigen lassen kann und es versteh, werd ich eh recht schnell an die Grenzen stoßen und was eigenes basteln müssen.

IDs solltest du ganz einfach so bekommen:


<?php foreach($model->pictures as $picture): ?>

  <div>Image: <?php echo $picture->ID ?> </div>

<?php endforeach; ?>

Danke! :D

Perfekt :D