So, I am helping to build this application that displays information about schools, and one of the "problems" is that for each school (represented by a single record in a single table), there are multiple related tables that may or may not have corresponding records in them. Most of these tables are related to the school table in a "has_one/belongs_to" manner.
The issue I'm encountering is that we have fatal errors from PHP when our view file tries to access properties of related models (e.g. echo $school->otherModel->someProperty) that have not been instantiated (because of the lack of a corresponding record).
The hack I came up with for this is extremely messy and goes a little something like this:
- Rewrite the school controller's loadModel() method so that after the school::model()->findByPk() method is called, I can
- loop through each of the items in the school's relations() array, and
- if the type of the item is not "object" (resulting from the HAS_ONE relationship) or "array" (from a HAS_MANY relationship),
- instantiate a new object $item, and
- Loop through each of the $item's attributes, and if it is one of the attributes I want to display,
- assign a default value to it (like "Data not available").
This solution *works* (sort of), but it is really ugly, and I'd like to find a much cleaner way to ensure that there are no "blank spaces" in my view file resulting from printing out attribute values that are null.
If anyone has any suggestions for a cleaner solution, I am all ears. If you live near me (Florida), I will even buy you a beer!
Thanks!
Tom
p.s. Here is my hack, to satisfy morbid curiosity:
public function loadModel()
{
if($this->_model===null)
{
if(isset($_GET['id']))
$this->_model=School::model()->with(
'admission',
'degree',
'enrollment',
'financialaid',
'graduation',
'insurers',
'lenders',
'testscore',
'tuition'
)->findbyPk($_GET['id']);
if($this->_model===null)
throw new CHttpException(404,'The requested page does not exist.');
}
// Loop through School model's related models, and if no corresponding
// object was created (i.e. there is no corresponding record in the
// database), then instantiate an empty instance of each missing model.
// This is designed to prevent PHP fatal errors when the view
// attempts to access properties of related models for which there
// may be no corresponding records in the database.
foreach(array_keys($this->_model->relations()) as $child)
{
$type = gettype($this->_model->$child);
if ($type != 'object' && $type != 'array')
{
$this->_model->$child = new $child; // e.g. if school doesn't have a (whatever), create one;
Yii::trace("Type of \$child is: " . gettype($child));
// Loop through $child's attributes and set value to
// application "data not available" string
if ($child != 'Lender' && $child != 'Insurance')
{
foreach($this->_model->$child->getAttributes() as $key=>$value)
{
if ($key != 'school_id' && (!stristr($key, 'Period')))
{
$this->_model->$child->setAttribute($key, CActiveRecordExtended::NA);
}
}
}
}
}
return $this->_model;
}

Help














