Search code examples
phpyii2relationshipyii2-advanced-appdataprovider

Yii2 - Trying to get property of non-object with relations


views/search.php

<?php foreach($dataProvider->getModels() as $call){ ?>
<tbody>
<tr>
    <td><?=$call->created?></td>
    <td><?=$call->call_datetime?></td>
    <td><?=$call->call_from?></td>
    <td><?=$call->call_to?></td>
    <td><?=$call->duration?></td>
    <td><?=$call->call_type?></td>
    <td><?=$call->extension?></td>
   <td><?=$call->callRecFiles->fname?></td> 
</tr>
</tbody>
<?php } ?>

relation in models/Call.php

 public function getCallRecFiles()
{
    return $this->hasOne(CallRecording::className(), ['callref' => 'callref']);
}

Controller actionSearch

public function actionSearch($id)
{
    $cust = new Customer();
    Yii::$app->user->identity->getId();
    $dataProvider = new ActiveDataProvider([
        'query' => Call::find()
            ->with('customer', 'callRecFiles') // eager loading relations 'customer' & 'callRecFiles' 
            ->where(['custref' => $id])
            ->limit(10),
        'pagination' => false, // defaults to true | when true '->limit()' is automatically handled
    ]);
    return $this->render('search',[
        'dataProvider' => $dataProvider,
        'cust' => $cust,
    ]);
}

What am i doing wrong here or missing? I have browsed other similar questions however all seem to be involving widgets or file input. Any help is appreciated.


Solution

  • There's two places where you can have error Trying to get property of non-object.

    First is here:

    <td><?=$call->callRecFiles->fname?></td>
    

    To avoid it, you should use if statement:

    <td><?= $call->callRecFiles ? $call->callRecFiles->fname : null ?></td>
    

    Second is here:

    Yii::$app->user->identity->getId();
    

    If there's no access controll rule in your controller, an unlogged user can access this action and search method, so you don't have identity of user until he logs in. To avoid it, you should add behaviors to your controller:

    /**
     * @inheritdoc
     */
    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::class,
                'rules' => [
                    [
                        'allow'         => true,
                        'roles'         => ['@'],
                    ],
                ],
            ],
        ];
    }
    

    It will require user to log in before accessing your actions in this controller.

    By the way, you are not using at all this code:

    Yii::$app->user->identity->getId();
    

    So removing it is also a solution.