Problem with GridView::widget

Hi guys,

I am new in Yii and I have a problem.

I wrote code for reading table from database with relational table and I want to display field from relational table in GridView::widget;

Code is bellow:




public function search($params)

    {


        $query = Usersnew::find()->addSelect('usersnew.Id, usersnew.FirstName,usersnew.LastName,usersnew.NickName,usersnew.IdCity,city.Naziv');

        $query->innerJoin('city', 'usersnew.IdCity=city.Id');


        $dataProvider = new ActiveDataProvider([

            'query' => $query,

            'pagination' => [

                'pageSize' => 5,

            ],


        ]);


        //print_r($dataProvider);


        $this->load($params);


        if (!$this->validate()) {

            // uncomment the following line if you do not want to return any records when validation fails

            // $query->where('0=1');

            return $dataProvider;

        }


        // grid filtering conditions


        $query->andFilterWhere([

            'Id' => $this->Id,

            'IdCity' => $this->IdCity,

        ]);


        $query->andFilterWhere(['like', 'FirstName', $this->FirstName])

            ->andFilterWhere(['like', 'LastName', $this->LastName])

            ->andFilterWhere(['like', 'NickName', $this->NickName]);


        return $dataProvider;

    }

}



And this code work. I have no problem at all. But when I try to show field Naziv in gridvew it breaks:





<?= GridView::widget([

        'dataProvider' => $dataProvider,

        'filterModel' => $searchModel,


        'columns' => [

            ['class' => 'yii\grid\SerialColumn'],


            'FirstName',

            'LastName',

            'NickName',

            'Naziv',

            ['class' => 'yii\grid\ActionColumn'],

        ],

    ]); ?>



Error says:

Unknown Property – yii\base\UnknownPropertyException

Getting unknown property: app\models\Usersnew::Naziv

I don’t know what is it because relation in php code works.

How to show field from related table?

thanx in advance

What does your Usersnew model look like?

Simply selecting an extra column does not put the value into your model. You need to define relations (see the guide for that).

Please use "code" tags when posting code.

Hi Patrick,

thank you for your help. I couldn’t find code tag. I am new at the forum :).

This is my model code:




class Usersnew extends \yii\db\ActiveRecord

{

    /**

     * @inheritdoc

     */

    public static function tableName()

    {

        return 'usersnew';

    }


    /**

     * @inheritdoc

     */

    public function rules()

    {

        return [

            [['FirstName', 'LastName', 'NickName', 'IdCity'], 'required'],

            [['IdCity'], 'integer'],

            [['FirstName', 'LastName', 'NickName'], 'string', 'max' => 100],


        ];

    }


    /**

     * @inheritdoc

     */

    public function attributeLabels()

    {

        return [

            'Id' => 'ID',

            'FirstName' => 'First Name',

            'LastName' => 'Last Name',

            'NickName' => 'Nick Name',


        ];

    }


    /**

     * @return \yii\db\ActiveQuery

     */

    public function getIdCity()

    {

        return $this->hasOne(City::className(), ['Id' => 'IdCity']);

    }

}






class UsersnewSearch extends Usersnew

{

    /**

     * @inheritdoc

     */

    public function rules()

    {

        return [

            [['Id', 'IdCity'], 'integer'],

            [['FirstName', 'LastName', 'NickName'], 'safe'],

        ];

    }


    /**

     * @inheritdoc

     */

    public function scenarios()

    {

        // bypass scenarios() implementation in the parent class

        return Model::scenarios();

    }


    /**

     * Creates data provider instance with search query applied

     *

     * @param array $params

     *

     * @return ActiveDataProvider

     */

    public function search($params)

    {


        $query = Usersnew::find()->addSelect('usersnew.Id, usersnew.FirstName,usersnew.LastName,usersnew.NickName,usersnew.IdCity,city.Naziv');

        $query->innerJoin('city', 'usersnew.IdCity=city.Id');


        $dataProvider = new ActiveDataProvider([

            'query' => $query,

            'pagination' => [

                'pageSize' => 5,

            ],


        ]);


        //print_r($dataProvider);


        $this->load($params);


        if (!$this->validate()) {

            // uncomment the following line if you do not want to return any records when validation fails

            // $query->where('0=1');

            return $dataProvider;

        }


        // grid filtering conditions


        $query->andFilterWhere([

            'Id' => $this->Id,

            'IdCity' => $this->IdCity,

        ]);


        $query->andFilterWhere(['like', 'FirstName', $this->FirstName])

            ->andFilterWhere(['like', 'LastName', $this->LastName])

            ->andFilterWhere(['like', 'NickName', $this->NickName]);


        return $dataProvider;

    }

}




I hope this helps.

Thank you again it is very important to me.

The code tag is in the editor’s toolbar, says “Insert code snippet”.

You need to define a relation in your model:

http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#relational-data

And then use it like this:

http://www.yiiframework.com/doc-2.0/guide-output-data-widgets.html#working-with-model-relations

Thank you very much Patrick. I fixed code tag. Will be in touch.

Thanx again.

Hi Patrick,

I did everything you say and still have problem with relation.

Here is my new code:

Model:




class Usersnew extends \yii\db\ActiveRecord

{

    /**

     * @inheritdoc

     */

    public static function tableName()

    {

        return 'usersnew';

    }


    public static function primaryKey()

    {

        return ['Id'];

    }


    /**

     * @inheritdoc

     */

    public function rules()

    {

        return [

            [['FirstName', 'LastName', 'NickName', 'IdCity'], 'required'],

            [['IdCity'], 'integer'],

            [['FirstName', 'LastName', 'NickName'], 'string', 'max' => 100],


        ];

    }


    /**

     * @inheritdoc

     */

    public function attributeLabels()

    {

        return [

            'Id' => 'ID',

            'FirstName' => 'First Name',

            'LastName' => 'Last Name',

            'NickName' => 'Nick Name',


        ];

    }


    /**

     * @return \yii\db\ActiveQuery

     */

    public function getIdCity()

    {

        return $this->hasOne(City::className(), ['Id' => 'IdCity']);

    }

}




class UsersnewSearch extends Usersnew

{

    /**

     * @inheritdoc

     */

    public function rules()

    {

        return [

            [['Id', 'IdCity'], 'integer'],

            [['FirstName', 'LastName', 'NickName'], 'safe'],

        ];

    }


    public function attributes()

    {

        // add related fields to searchable attributes

        return array_merge(parent::attributes(), ['city.Naziv']);

    }


    /**

     * @inheritdoc

     */

    public function scenarios()

    {

        // bypass scenarios() implementation in the parent class

        return Model::scenarios();

    }


    /**

     * Creates data provider instance with search query applied

     *

     * @param array $params

     *

     * @return ActiveDataProvider

     */

    public function search($params)

    {


        //$query = Usersnew::find()->addSelect('usersnew.Id, usersnew.FirstName,usersnew.LastName,usersnew.NickName,usersnew.IdCity,city.Naziv');

        $query = Usersnew::find();

        //$query->innerJoin('city', 'usersnew.IdCity=city.Id');

        $query->joinWith(['city' => function($query) { $query->from(['city' => 'usersnew']); }]);




        $dataProvider = new ActiveDataProvider([

            'query' => $query,

            'pagination' => [

                'pageSize' => 5,

            ],


        ]);


        //print_r($dataProvider);


        $this->load($params);


        if (!$this->validate()) {

            // uncomment the following line if you do not want to return any records when validation fails

            // $query->where('0=1');

            return $dataProvider;

        }


        // grid filtering conditions


        $query->andFilterWhere([

            'Id' => $this->Id,

            'IdCity' => $this->IdCity,

        ]);


        $query->andFilterWhere(['like', 'FirstName', $this->FirstName])

            ->andFilterWhere(['like', 'LastName', $this->LastName])

            ->andFilterWhere(['like', 'NickName', $this->NickName]);


        return $dataProvider;

    }

}




Controller:




class UsersnewController extends Controller

{

    /**

     * @inheritdoc

     */

    public function behaviors()

    {

        return [

            'verbs' => [

                'class' => VerbFilter::className(),

                'actions' => [

                    'delete' => ['POST'],

                ],

            ],

        ];

    }


    /**

     * Lists all Usersnew models.

     * @return mixed

     */

    public function actionIndex()

    {

        $searchModel = new UsersnewSearch();

        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);


        return $this->render('index', [

            'searchModel' => $searchModel,

            'dataProvider' => $dataProvider,

        ]);

    }


    /**

     * Displays a single Usersnew model.

     * @param string $id

     * @return mixed

     */

    public function actionView($id)

    {

        return $this->render('view', [

            'model' => $this->findModel($id),

        ]);

    }


    /**

     * Creates a new Usersnew model.

     * If creation is successful, the browser will be redirected to the 'view' page.

     * @return mixed

     */

    public function actionCreate()

    {

        $model = new Usersnew();


        if ($model->load(Yii::$app->request->post()) && $model->save()) {

            return $this->redirect(['view', 'id' => $model->Id]);

        } else {

            return $this->render('create', [

                'model' => $model,

            ]);

        }

    }


    /**

     * Updates an existing Usersnew model.

     * If update is successful, the browser will be redirected to the 'view' page.

     * @param string $id

     * @return mixed

     */

    public function actionUpdate($id)

    {

        $model = $this->findModel($id);


        if ($model->load(Yii::$app->request->post()) && $model->save()) {

            return $this->redirect(['view', 'id' => $model->Id]);

        } else {

            return $this->render('update', [

                'model' => $model,

            ]);

        }

    }


    /**

     * Deletes an existing Usersnew model.

     * If deletion is successful, the browser will be redirected to the 'index' page.

     * @param string $id

     * @return mixed

     */

    public function actionDelete($id)

    {

        $this->findModel($id)->delete();


        return $this->redirect(['index']);

    }


    /**

     * Finds the Usersnew model based on its primary key value.

     * If the model is not found, a 404 HTTP exception will be thrown.

     * @param string $id

     * @return Usersnew the loaded model

     * @throws NotFoundHttpException if the model cannot be found

     */

    protected function findModel($id)

    {

        if (($model = Usersnew::findOne($id)) !== null) {

            return $model;

        } else {

            throw new NotFoundHttpException('The requested page does not exist.');

        }

    }

}




Index view with GridView:




<?php


use yii\helpers\Html;

use yii\grid\GridView;

use app\models\City;


/* @var $this yii\web\View */

/* @var $searchModel app\models\UsersnewSearch */

/* @var $dataProvider yii\data\ActiveDataProvider */


$this->title = 'Usersnews';

$this->params['breadcrumbs'][] = $this->title;

?>

<div class="usersnew-index">


    <h1><?= Html::encode($this->title) ?></h1>

    <?php // echo $this->render('_search', ['model' => $searchModel]); ?>


    <p>

        <?= Html::a('Create Usersnew', ['create'], ['class' => 'btn btn-success']) ?>

    </p>

    <?= GridView::widget([

        'dataProvider' => $dataProvider,

        'filterModel' => $searchModel,


        'columns' => [

            ['class' => 'yii\grid\SerialColumn'],

            ['class' => 'yii\grid\ActionColumn'],

        ],

    ]); ?>

</div>


And after all that it shows error:




[code]


Invalid Parameter – yii\base\InvalidParamException


app\models\Usersnew has no relation named "city".

↵

Caused by: Unknown Method – yii\base\UnknownMethodException


Calling unknown method: app\models\Usersnew::getcity()


in C:\wamp\www\ctb\vendor\yiisoft\yii2\base\Component.php at line 285




I have 2 tables: city and usersnew. They are related by fields usersnew.IdCity=city.Id in PhPMyAdmin designer. They have PK and FK. I have checked.

I don’t know what is wrong I did everything that is in docs.

Please help :)

thanx in advance

Look at the error message:

Your model "Usersnew" indeed has not relation named city. It has a relation named "idCity":




    public function getIdCity()

    {

        return $this->hasOne(City::className(), ['Id' => 'IdCity']);

    }



So try and rename that to "city".

Important thing to know is that a function “getCity” defines a relation by the name of “city”. Here’s more on that: http://www.yiiframework.com/doc-2.0/guide-concept-properties.html

Hi Patrick, dear Patrick :)

it now works.

But there is little problem.

Filter above GridView does not exists for city names and name of the related cities is black.

How to fix that?

best regards

Read the guide, mate:

http://www.yiiframework.com/doc-2.0/guide-output-data-widgets.html#working-with-model-relations

Dear Patrick,

i would like to thank you for your effort to help me. I own you a lot.

Everything works perfect now.

best regards

You own me or you owe me? Only one of those I’m somewhat comfortable with…

You’re welcome.

Sorry, my mistake. I owe you a lot :)

thanx again mate

Hi Patrick it is me again :)

Just one simple question for you. I would like to execute simple query in Yii. Something like "SELECT * FROM Users". Because I need it urgent. Can you paste me some lines of code with example. I was reading documentation but everything I tried does not work.

best regards

For a different issue, please start a new topic.

OK Patrick, thank you very much for guide.

Dear Patrick,

hi again. I have one simple question. How did you conclude that my relation name is "idCity". I can`t figure it.

best regards

Each relation method must be named as getXyz. We call xyz (the first letter is in lower case) the relation name. Note that relation names are case sensitive.

FYI, your relation method name as getIdCity(). So relation name as idCity.

For more info: http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#declaring-relations

Ok I am getting now. But one simple question. If my method name is getIdCity() with capital "I" why relation name is idCity with lowercase "I"?

regards

It’s just a convention: http://www.yiiframework.com/doc-2.0/guide-concept-properties.html

Thank you very much:)

best regards