Hi, I’m relatively new to MVC designs in general and I’m having some issues trying to figure out the best/most appropriate way of accomplishing things. I’d greatly appreciate any feedback on strategies. I’ll detail a few I’ve tried so far.
So, I’m getting started on my first project with Yii (a polling site). I started with a nice little relational database, used the yiic shell command to model and crud some basic stuff. I made sure my relations worked right so I could link the poll to the choices, votes and users. This part I get, but it’s easier because it’s focused on the poll model and it’s relationships, and it’s all driven by the PollController.
What I’m trying to do now is put multiple views together (ie. for the home page). I want a list of polls as well as some other views, such as a subject list. One of my questions is what exactly drives this. Obviously, it’s the index action of the site controller. But does this mean that I have collect all my data from various models within this controller? This is where I’m hung up. If I have a view I want to use, the data for that view is in a specific method of a controller. I can call any view from any controller, but I can’t pass it the right data unless the same logic that’s in the right controller is also in the site controller. This just seems crazy to me, so I’m sure I’m doing it wrong.
Here’s what I have just done for my homepage. I have a list of Subjects and a list of Polls. I built a widget for the subjects and just call the view for the polls.
SiteController > actionIndex()
public function actionIndex()
{
$polls=Poll::model()->findAll();
$this->render('index', array('models'=>$polls));
}
views/site/index.php
$this->widget('application.components.SubjectTree');
$this->renderPartial('/issue/listbox', array('models'=>$models));
components/SubjectTree.php
class SubjectTree extends CTreeView
{
public function init()
{
$subjectList=Subject::model()->findAllByAttributes(array('parent_id'=>null));
foreach($subjectList as $subject){
$children = Subject::model()->findAllByAttributes(array('parent_id'=>$subject['id']));
$kids = array();
$hasKids = false;
foreach($children as $child){
$kids[] = array(
'id'=>$child['id'],
'text'=>$child['name'],
);
$hasKids = true;
}
$subjects[] = array(
'id'=>$subject['id'],
'text'=>'<a class="subject-link" id="a-subject-'.$subject['id'].'">'.$subject['name'].'</a>',
'expanded'=>false,
'hasChildren'=>$hasKids,
'children'=>$kids,
);
}
$this->data = $subjects;
$cs=Yii::app()->getClientScript();
$cs->registerCoreScript('jquery');
$cs->registerScriptFile('/poll/js/stjava.js');
parent::init();
}
public function run()
{
parent::run();
}
}
I like the idea of the widget containing it’s own data logic because it keeps the site controller more clean. As for the Poll thing, I don’t like that I have to retrieve all the poll models in the site controller… I wish there was a way to interact with Poll as an object and tell it to get it’s own data for whatever particular view I need.
So, in general and specifically in terms of what I have shown here, what are the correct strategies for bringing together multiple different views?
Thanks, Jaz