Model Vs Database access

Hello all,

I have 2 questions regarding best-practice style in Yii (including performance when developing a site intended for 50,000+ users)

Here goes… I have this DB

People —< Sugestion >— Product —< StoreXProduct >— Store

all have their unique id w/ the following format:


Table      Key       Foreign-Key

People     id

Sugestion  id        people_id

...

1st question)

What is the best way (efficient) to retrieve data (or is it the same)?

I have accessed data through




$criteria=new CDbCriteria(array(

			'condition'=>'people_id='.$id,

		));

$dataProvider=new CActiveDataProvider('Sugestion', array(

			'criteria'=>$criteria,

		));

$this->render('view',array(

			'dataProvider'=>$dataProvider,

                        ...



But recently I want to take a more OO approach, like




   $person= People::model()->find('id=?',array($id));

		$this->render('view',array(

			'person'=>$person

		));

and in the view I only have to use


$person->name

instead of


$dataProvider->data[0]->name

which in this case (since it is a search by PKey) will only retrieve 1 answer.

My thoughts: Use OO (much cleaner code) whenever possible.

But use dataProvider when you need to work with CListView.

[color="#0000FF"]

Is this line of thought correct?

But which is more or less efficient?

[/color]

2nd question)

Now that I have that one person which I am looking for (in OO style), I want to use this object and just traverse through the relationship.

In the view I can display


$person->sugestions->product_id ; // which displays a number CORRECTLY

but now I want to display the actual product name (stored in Products Object)


$person->sugestions->product->name ; // which does NOT work

This does not work.

[color="#0000FF"]Should I use another CActiveDataProvider but now with a different model?

Is there an OO Style to do this?

[/color]

Here are the models

[b]people

[/b]


	public function relations()

	{

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

		// class name for the relations automatically generated below.

		return array(

                          ...

                          'sugestions' => array(self::HAS_MANY, 'Sugestion', 'people_id'),

                          ...




sugestion




	public function relations()

	{

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

		// class name for the relations automatically generated below.

		return array(

			'people' => array(self::BELONGS_TO, 'People', 'people_id'),

			'product' => array(self::BELONGS_TO, 'Product', 'product_id'),

		);

	}

product


	public function relations()

	{

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

		// class name for the relations automatically generated below.

		return array(

			'storexproducts' => array(self::HAS_MANY, 'StoreXProduct', 'product_id'),

			'sugestions' => array(self::HAS_MANY, 'Sugestion', 'product_id'),

		);

	}

I looked at http://www.yiiframework.com/doc/guide/1.1/en/database.arr and used the with method (and also changed the people model)


'products'=>array(self::HAS_MANY,'Product','product_id','through'=>'sugestions'),

But none seem to work. Help

Thanks in advanced

Ok … got a partial response for the 2nd question.

What I did was change the People model. Added the following to public function relations()


'products'=>array(self::HAS_MANY,'Product','product_id','through'=>'sugestions'),



Then in view


foreach($person->products as $key => $value)  {

            $value->name ;

}

But this raises another question.

Why do I have to create an extended relationship by using "through"?

Why can’t I just use $model1->$model2->$model3->fieldModel3?

Why do I have to create in Model1




			'model2' => array(self::HAS_MANY, 'table1', 'fkey'),

			'model3' => array(self::HAS_MANY, 'table2','fkey','through'=>'model2s'),



And instead of using $model1->$model2->$model3->fieldModel3 I have to use $model1->$model3->fieldModel3?

Try it with eager loading like this




$person= People::model()->with('suggestion', 'suggestion.product')->find('id=?',array($id));


or (one single query)


$person= People::model()->with('suggestion', 'suggestion.product')->together()->find('id=?',array($id));



or like this (data provider compatible syntax)




$crit = new CDbCriteria(array(

  'condition' => 'id=:id',

  'params' => array(':id' => $id),

  'with' => array(

    'suggestion' => array(

      'with' => array(

        'product'

      ),

    ),

  ),

  //'together' => true,

));


usage:

$person = People::model()->find($crit);

or

$dp = new CActiveDataProvider('People', $crit);

$person = $dp->data;



(not tested now)

/Tommy

Thanks