[SOLVED] 2 models 1 view

I have read all the threads about this that I can find and none of them seem to cover my situation.

Starting from the blog demo I added a Media model to handle images.

I also added the facility to tag images based on the existing tag model.

This all works fine.

The next step is getting the images to show up when you click a word in the tag cloud.

So although the 2 models I want to include are related, Post and Media, I’m not querying them in a related way.

I just want all posts and all images tagged with a certain word.

Any ideas how I can pass both models to the view?

THis way:

In the controller:




$this->render('theView',array('model1'=>$modelA,'model2'=>$modelB));



And in the view you can access $model1 (corresponds to $modelA) or $model2 (corresponds to $modelB)

You can pass all models or variables as you need.

I did try this, but couldn’t get it to work.

I just had another go and managed it :)

How I got it to work seems a little odd though, in my controller -


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

	'dataProvider'=>$dataProvider,

	'dataProvider2'=>$dataProvider2,  //  <------seems odd

));

in my view -


$this->widget('zii.widgets.CListView', array(

	'dataProvider'=>$dataProvider,

	'itemView'=>'_view',

	'template'=>"{items}\n{pager}",

));

$this->widget('zii.widgets.CListView', array(

	'dataProvider'=>$dataProvider2,

	'itemView'=>'phview',

	'template'=>"{items}\n{pager}",

));

Seems odd that I can do that on the marked line.

I guess that points to me not fully understanding how all this works yet.

Thanks for the help though, really appreciate it.

Did you effectively have two DataProviders in your controller?

I say:

Did you do this:




$dataProvider = new CActiveDataProvider; // (o whatever you use)

$dataProvider2 = new CActiveDataProvider;



Yes, I didn’t post the whole action to keep it brief.

But yes, I setup 2 DataProviders like you said.

Strange! this is the way to go to pass variables (model or whatever) from the controller to the view…

May be a bug in CListView?

Or some error is thrown to you?

No errors at all, nothing in application.log, it is working as I want it to.

Here is the full actionIndex (I made a few more changes since I fixed it, but it still works) -


public function actionIndex()

{

        $criteria=new CDbCriteria(array(

                'condition'=>'status='.Post::STATUS_PUBLISHED,

                'order'=>'update_time DESC',

                'with'=>'commentCount',

                'with'=>'mediaCount',

        ));

        if(isset($_GET['tag']))

                $criteria->addSearchCondition('tags',$_GET['tag']);

        if(isset($_GET['type']))

                $criteria->addSearchCondition('type',$_GET['type']);


        if(isset($_GET['tag'])) {

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

                        'criteria'=>$criteria,

                ));

        } else {

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

                        'pagination'=>array(

                                'pageSize'=>Yii::app()->params['postsPerPage'],

                        ),

                        'criteria'=>$criteria,

                ));

        }

        if(isset($_GET['tag'])) {

                $criteria2=new CDbCriteria(array(

                        'order'=>'upload_time DESC',

                ));

                $criteria2->addSearchCondition('tags',$_GET['tag']);

                if(isset($_GET['type'])) {

                        $criteria2->addSearchCondition('type',$_GET['type']);

                }

                $dataProvider2=new CActiveDataProvider('Media', array(

                        'criteria'=>$criteria2,

                ));

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

                        'dataProvider'=>$dataProvider,

                        'dataProvider2'=>$dataProvider2,

                ));

        } else {

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

                        'dataProvider'=>$dataProvider,

                ));

        }

}

There have been a few other strange things though, I can’t get CWebLogRoute working.

From main.php -


'log'=>array(

	'class'=>'CLogRouter',

	'routes'=>array(

		array(

			'class'=>'CFileLogRoute',

			'levels'=>'error, warning'

		),

		array(

			'class'=>'CWebLogRoute',

                        'levels'=>'trace, info, error, warning'

		),

	),

),

Also, I don’t always get the flash message when submitting a form.

Sometimes all submitting the form appears to do is refresh the page.

Maybe there is something wrong with my setup?

Mmmm…

Did you check your code carefully.

Why you do this?




if(isset($_GET['tag'])) {

   //some code

} else {

   // some other code

}


if(isset($_GET['tag'])) {

   // some more other code

} else {

  // some more more other code

}



You are checking twice!

Why not do all that in just one if/else structure…

May be is a problem with the flow of your code…

doh! As if I didn’t look like a big enough noob already…

I don’t know why I did that, it was only a few hours ago so I like to think I would of noticed eventually :)

I changed it to 1 if else statement and it still works as expected.

Reworked -


public function actionIndex()

{

        $criteria=new CDbCriteria(array(

                'condition'=>'status='.Post::STATUS_PUBLISHED,

                'order'=>'update_time DESC',

                'with'=>'commentCount',

                'with'=>'mediaCount',

        ));

        if(isset($_GET['tag'])) {

                $criteria2=new CDbCriteria(array(

                        'order'=>'upload_time DESC',

                ));

                $criteria->addSearchCondition('tags',$_GET['tag']);

                $criteria2->addSearchCondition('tags',$_GET['tag']);

                if(isset($_GET['type'])) {

                        $criteria->addSearchCondition('type',$_GET['type']);

                        $criteria2->addSearchCondition('type',$_GET['type']);

                }

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

                        'criteria'=>$criteria,

                ));

                $dataProvider2=new CActiveDataProvider('Media', array(

                        'criteria'=>$criteria2,

                ));

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

                        'dataProvider'=>$dataProvider,

                        'dataProvider2'=>$dataProvider2,

                ));

        } else {

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

                        'pagination'=>array(

                                'pageSize'=>Yii::app()->params['postsPerPage'],

                        ),

                        'criteria'=>$criteria,

                ));

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

                        'dataProvider'=>$dataProvider,

                ));

        }

}

Don’t worry… may be you are so tired to work now… and when you rest a little, you can see this with new eyes!!

By the way:

What happens when this codes executes?

You’re probably right, I can’t stop though! Yii is fun!

When the code executes everything goes according to plan.

Both models are passed to the view and the view renders them no problems.

So, your problem is solved!!!

Cool!

It is, my page works, and I’m starting to understand better.

Many thanks for your help :)

I do this in admin view…the 2 models(tables) are displayed…

But when I try to edit one record from the second table it references the first table…

How come??

Please help