Dealing with null relation properties in CDetailView

Hello

I am new to Yii and quite rusty with my PHP in general. I have been setting up a Yii project, and while so far I have made some good progress, I am running into problems with null/none-existent relational data.

For example, say I have two tables:

Customer:

idcustomer

customer_name

fk_location

Location:

idlocation

office

Table Customer has a foreign key fk_location linked to idlocation on the Location table.

So far so simple.

Now, in Yii I have a relation called "location" set up under the Relations method in my Customer Model which correctly points to the Location table. Now, when a Customer record has a location, everything works great.

However, not all customers in the table will have a location [if it matters, location refers to offices within the building, not all customers are in the building]. Whenever my views try to display data that has a null foreign key, the views throw a wobbler since $model->location does not exist.

I thought I had found the answer when I saw a post on here saying the relations method supported a "createIfNull" option - apparently that person was wrong since it did nothing nor have I found any documentation on it.

So, in short, how would I modify this:


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

	'data'=>$model,

	'attributes'=>array(

                'customer_name',

		//...

		array(

			'label'=>'Location',

			'type'=>'raw',

			'value'=>CHtml::encode($model->location->office,

		),

),

if a particular customer record has no location and therefore neither $model->location or $model->location->office exist.

I tried using CValidator::isEmpty, but it didn’t like being used from within the view file and I am not sure putting in a bunch of conditional code in the view file is the best way to sort this out.

Am I missing something really obvious, or is it assumed null foreign links are evil and no one would dare use them?

Currently I am toying with the idea of creating special records in my tables that basically contain "N/A" to avoid this, but I would rather not fill my tables with a bunch of dummy records to get around this issue.

Any help would be greatly appreciated!

I don’t think that you can avoid logic in views cause you often could have such cases where a value can be null and you have to handle that.

In your case you can use a short conditional if statement to check if your $model->location exists.


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

	'data'=>$model,

	'attributes'=>array(

                'customer_name',

		//...

		array(

			'label'=>'Location',

			'type'=>'raw',

                        // EDIT: fixed missing ! in front of empty()

			'value'=>(!empty($model->location)) ? CHtml::encode($model->location->office) : 'N/A',

		),

),

Hi kokomo!

Thank you for your reply. Your suggestion did the trick and things are running smoothly again.

I should point out that in your ternary operator example, you have the true/false statements the wrong way around. It took a mug of coffee for me to spot that error this morning! :)

Good to hear that it worked for you.

Edited my post above and fixed conditional if statement.

Little extra information on the side:

If you use NULL instead of ‘N/A’ in the statement the widget will display the default nullDisplay value of the CDetailView.