Using Our Models To Do Basic Queries On The DB
The application has an auto-generated model, Gii kindly provides the model once the database is created.
01 <?php02 class Product extends CActiveRecord03 {04 /**05 * The followings are the available columns in table 'Product':06 * @var integer $id07 * @var integer $brandId08 * @var string $name09 * @var string $price10 */11 12 /**13 * Returns the static model of the specified AR class.14 * @return CActiveRecord the static model class15 */16 public static function model($className=__CLASS__)17 {18 return parent::model($className);19 }20 21 /**22 * @return string the associated database table name23 */24 public function tableName()25 {26 return 'Product';27 }28 29 /**30 * @return array validation rules for model attributes.31 */32 public function rules()33 {34 return array(35 array('name','length','max'=>255),36 array('price','length','max'=>8),37 array('name, price', 'required'),38 );39 }40 41 /**42 * @return array relational rules.43 */44 public function relations()45 {46 // NOTE: you may need to adjust the relation name and the related47 // class name for the relations automatically generated below.48 return array(49 'brand' => array(self::BELONGS_TO, 'Brand', 'brandId'),50 'categories' => array(self::MANY_MANY, 'Category', 'ProductCategory(productId, categoryId)'),51 );52 }53 54 /**55 * @return array customized attribute labels (name=>label)56 */57 public function attributeLabels()58 {59 return array(60 'id'=>'Id',61 'brandId'=>'Brand',62 'name'=>'Name',63 'price'=>'Price',64 );65 }66 }
Enable your weblogger: this you will find in: /yourProject/protected/config/main.php
By default your log array looks something like this: (Tip: IF you haven’t done this, and you find it hard to find you way in the file, comment everything you deem meaningful, use spaces and limit blocks of codes with comment of your choice)
1 'log'=>array(2 'class'=>'CLogRouter',3 'routes'=>array(4 array(5 'class'=>'CFileLogRoute',6 'levels'=>'error, warning',7 ),8 ),9 ),
Let’s add in the CWebLogRoute so it looks like this.
01 'log'=>array(02 'class'=>'CLogRouter',03 'routes'=>array(04 array(05 'class'=>'CFileLogRoute',06 'levels'=>'error, warning',07 ),08 array(09 'class'=>'CWebLogRoute',10 'levels'=>'trace,info, error, warning',11 ),12 ),13 ),
Visit the application and notice that at the bottom of the screen a table is shown displaying everything Yii does to make it possible for the website to be shown correctly. This is especially useful when you’re new to the Yii DB stuff.
Let’s start by getting all of our products. If you are trying this tutorial, then please create a simple new installation, config the database settings in /protected/config/main.php and create your database with the proposed columns from the model seen earlier.
You can test this in any controller, because the system already has a default SiteController in: /protected/controllers/siteController.php, this tutorial will use siteController.php with the view-file in: /protected/views/site/index.php
So we’ll first modify our SiteController::actionIndex method.
1 public function actionIndex()2 {3 $this->render('index', array(4 'Products' => Product::model()->findAll(),5 ));6 }
Open the view-file related to the actionIndex() The system has an array that will be passed to our index view. This array contains ‘Products’ which will be usable as ‘$Products’ in our view: /protected/views/site/index.php
01 <?php $this->pageTitle=Yii::app()->name; ?>02 03 <h1>04 Welcome, <?php echo Yii::app()->user->name; ?>!05 </h1>06 <table>07 <?php foreach($Products AS $Product):?>08 <tr>09 <td><?php echo $Product->name;?></td>10 <td><?php echo $Product->price;?></td>11 </tr>12 <?php endforeach;?>13 </table>
The system (Yii) writes the SQL statements for us thanks to the AR and everything behind that, but we got back an array of product objects.
Now let’s use the ‘brand’ relation that is set in our Product model.
Without changing the controller, we can simply change the view and add the line to output the brand name.
1 <td><?php echo $Product->brand->name;?></td>
Now how did Yii do that? Look at the screen logger. You will see that it used the ‘lazy-loading’ technique to query the Brand table at that point.
1 Querying SQL: SELECT * FROM `Product`2 3 Querying SQL: SELECT `Product`.`id` AS `t0_c0`, t1.`id` AS `t1_c0`,4 t1.`name` AS `t1_c1`, t1.`website` AS `t1_c2` FROM `Product` LEFT OUTER5 JOIN `Brand` t1 ON (`Product`.`brandId`=t1.`id`) WHERE (`Product`.`id`=3)6 7 Querying SQL: SELECT `Product`.`id` AS `t0_c0`, t1.`id` AS `t1_c0`,8 t1.`name` AS `t1_c1`, t1.`website` AS `t1_c2` FROM `Product` LEFT OUTER9 JOIN `Brand` t1 ON (`Product`.`brandId`=t1.`id`) WHERE (`Product`.`id`=4)
This is not the best way to go so let’s change the actionIndex in siteController.php
1 public function actionIndex()2 {3 // renders the view file 'protected/views/site/index.php'4 // using the default layout 'protected/views/layouts/main.php'5 $this->render('index', array(6 'Products' => Product::model()->with(array('brand'))->findAll(),7 ));8 }
One query is all that is needed for all the data to be collected.
1 Querying SQL: SELECT `Product`.`id` AS `t0_c0`, `Product`.`brandId` AS2 `t0_c1`, `Product`.`name` AS `t0_c2`, `Product`.`price` AS `t0_c3`, t1.`id`3 AS `t1_c0`, t1.`name` AS `t1_c1`, t1.`website` AS `t1_c2` FROM `Product`4 LEFT OUTER JOIN `Brand` t1 ON (`Product`.`brandId`=t1.`id`)
The view file does not have to change for this. This technique is called eager-loading and has advantages over lazyloading sometimes.
This tutorial is a modified tutorial from another website/blog that unfortunantly isn’t online anymore, domain is being sold by godaddy.com, so I search my archives to retrieve this on, and post him here, hence a few additions, deletes and rewrites from me.

