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; }