Relations() Mysql Join

Witam,

raczkuje dopiero w yii i nie mogę poradzić sobie z relations()

posiadam 2 tablice mysql zawodnik i klub

wygernerowałem CRUD dla zawodnika tak wygląda moje wyświetlanie zawodników (index)


<?php $this->widget('MyGridView', array(

	'id'=>'zawodnik-grid',

	'dataProvider'=>$dataProvider,

	'selectionChanged'=>"function(id){window.location='"

          .Yii::app()->urlManager->createUrl('zawodnik/view',array('id'=>''))."' + 

          $.fn.yiiGridView.getSelection(id);}",

	'columns'=>array(

		'imie',

		'nazwisko',

		'przynaleznosc_klubowa',

	),

));

 ?>



teraz w przynaleznosc_klubowa wyświetla mi się 1

jak utworzyć relacje i wyświetlić nazwę klubu z tabeli tbl_club

zmień:


    

    'przynaleznosc_klubowa', 



na :




    array(

        'header'=>'Twoj nagłowek',

        'value'=> '$data->klub->nazwaColumnyTabeli',

    ),



czyli :




<?php $this->widget('MyGridView', array(

        'id'=>'zawodnik-grid',

        'dataProvider'=>$dataProvider,

        'selectionChanged'=>"function(id){window.location='"

          .Yii::app()->urlManager->createUrl('zawodnik/view',array('id'=>''))."' + 

          $.fn.yiiGridView.getSelection(id);}",

        'columns'=>array(

                'imie',

                'nazwisko',

                array(

                    'header'=>'Przynalezność Kluboowa',

                    'value'=> '$data->klub->nazwaColumnyTabeli'               

                ),

        ),

));

 ?>



Powinno wyswietlic dane z tablicy tbl_club. Oczywiście, jeżeli taka relacja była ustawiona pomiędzy tabelami zawodnik i klub.

Więcej poczytaj na :

http://www.yiiframework.com/forum/index.php/topic/33864-cgridview-and-column-name/

albo na

http://www.yiiframework.com/doc/api/1.1/CDataColumn

właśnie nie mam takiej relacji ustawionej i nie dociera do mnie jak mogę ustawić taką relacje

czy mam ją ustawić w obu modelach czy tylko w jednym modelu

w dokumentacji jest napisane


'VarName'=>array('RelationType', 'ClassName', 'ForeignKey', ...additional options)

czyli w modelu zawodnik powinienem dodać ?


'name'=>array('self::BELONGS_TO', 'Klub', 'nazwa'

w modelu zawodnik:


public function relations()

{

    return array(

                     //zawodnik należy do klubu

      'klub' => array(self::BELONGS_TO, 'Klub', 'przynaleznosc_klubowa'),    

    );


}

w modelu klub:


public function relations()

{

    return array(

                            //klub posiada wielu zawodnikow

        'zawodnik' => array(self::HAS_MANY, 'Zawodnik', 'przynaleznosc_klubowa'),

    );

}

trochę przerobiłem cały kod żeby potestować trochę

w modelu zawodnika mam




public function relations()

	{

	return array(

		'klub' => array(self::BELONGS_TO, 'Klub','przynaleznosc_klubowa'),

		);

}



wygenerowałem nowy kod w _View i skasowałem większość żeby był czytleny




<div class="view">

	<b><?php echo CHtml::encode($data->getAttributeLabel('Nazwa Klubu')); ?>:</b>

	<?php echo $data->klub->nazwa; ?> <- linia 9

	<br />

</div>



efektem jest błąd

PHP notice

Trying to get property of non-object

C:\xampp\htdocs\test\protected\views\zawodnik\_view.php(9)

dodam jeszcze ze mam 2 tabele w mysql

zawodnik

-id_zawodnika

-imie

-nazwisko

-przynaleznosc_klubowa

klub

-id_klubu

-nazwa


SELECT * FROM zawodnik LEFT JOIN klub ON przynaleznosc_klubowa = id_klubu

Witam

  1. Na marginesie, w ostatnim poście masz błąd bo próbujesz użyć metody z nie obiektu, więc nie chodzi o relacje.

[b]*************************************************************************************************************

ponieważ w yii zastosowano pewne rozwiązania zgodne z zasadami inżynierii oprogramowania,yii zakłada, że każda tabela ma pole "id" zadeklarowane jako PK (nie "id_zawodnika", nie "id_klubu") wtedy można skrócić parametryzowanie konfiguracji.

****************************************************************************************************************[/b]

Jeżeli robisz to inaczej to powinieneś skonfigurować swoją relację tak :




public function relations()

    {

        return array(

            'klub'=>array(self::BELONGS_TO, 'Klub', array('przynaleznosc_klubowa'=>'id_klubu')),//array('fk'=>'pk')

        );

    }



gdzie w tablicy podajesz niestandardowe przypisanie PK->FK, teraz jak poprawisz swój model będziesz mógł użyć:




    $data->klub->nazwa



>>> thanks god it’s friday <<<

Niestety poprawienie relacji nic mie zmienia dalej jest ten sam błąd i nie wiem co może być jego przyczyną ;/

w kodzie nie było nic ruszane oprócz relacji w modelu użytkownika i view

Jak nie tajemnica, wklej aktualny kod:

  1. cały model zawodnik i klub

  2. akcję z kontrolera, która to obsługuje

  3. cały widok

  4. jaki błąd dokładnie wystąpił ?

MODEL ZAWODNIK


<?php

class Zawodnik extends CActiveRecord

{


	public function tableName()

	{

		return '{{zawodnik}}';

	}




	public function rules()

	{

		return array(

			array('imie, nazwisko, wiek, waga, przynaleznosc_klubowa, opis_zawdonika', 'required'),

			array('wiek, waga, przynaleznosc_klubowa', 'numerical', 'integerOnly'=>true),

			array('imie, nazwisko', 'length', 'max'=>75),


			array('id_zawodnika, imie, nazwisko, wiek, waga, przynaleznosc_klubowa, opis_zawdonika', 'safe', 'on'=>'search'),

		);

	}


	public function relations()

    {

        return array(

            'test'=>array(self::BELONGS_TO, 'Klub', array('przynaleznosc_klubowa'=>'id_klubu')),//array('fk'=>'pk')

        );

    }


	public function attributeLabels()

	{

		return array(

			'id_zawodnika' => 'Id Zawodnika',

			'imie' => 'Imie',

			'nazwisko' => 'Nazwisko',

			'wiek' => 'Wiek',

			'waga' => 'Waga',

			'przynaleznosc_klubowa' => 'Przynaleznosc Klubowa',

			'opis_zawdonika' => 'Opis Zawdonika',

		);

	}


	public function search()

	{

		$criteria=new CDbCriteria;


		$criteria->compare('id_zawodnika',$this->id_zawodnika);

		$criteria->compare('imie',$this->imie,true);

		$criteria->compare('nazwisko',$this->nazwisko,true);

		$criteria->compare('wiek',$this->wiek);

		$criteria->compare('waga',$this->waga);

		$criteria->compare('przynaleznosc_klubowa',$this->przynaleznosc_klubowa);

		$criteria->compare('opis_zawdonika',$this->opis_zawdonika,true);


		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

		));

	}


	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}

}




MODEL KLUB


<?php


class Klub extends CActiveRecord

{


	public function tableName()

	{

		return '{{klub}}';

	}




	public function rules()

	{

		return array(

			array('nazwa, opis_klubu, id_trenera', 'required'),

			array('id_trenera', 'numerical', 'integerOnly'=>true),

			array('nazwa', 'length', 'max'=>255),


			array('id_klubu, nazwa, opis_klubu, id_trenera', 'safe', 'on'=>'search'),

		);

	}




	public function relations()

	{

		return array(

		);

	}


	public function attributeLabels()

	{

		return array(

			'id_klubu' => 'Id Klubu',

			'nazwa' => 'Nazwa',

			'opis_klubu' => 'Opis Klubu',

			'id_trenera' => 'Id Trenera',

		);

	}


	public function search()

	{


		$criteria=new CDbCriteria;


		$criteria->compare('id_klubu',$this->id_klubu);

		$criteria->compare('nazwa',$this->nazwa,true);

		$criteria->compare('opis_klubu',$this->opis_klubu,true);

		$criteria->compare('id_trenera',$this->id_trenera);


		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

		));

	}


	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}

}



VIEW ZAWODNIK




<div class="view">




	<b>KLUB:</b>

	<?php echo $data->test->nazwa; ?>

	<br />


</div>

ZAWODNIK CONTROLLER


<?php


class ZawodnikController extends Controller

{


	public $layout='//layouts/column2';


	public function filters()

	{

		return array(

			'accessControl',

			'postOnly + delete', 

		);

	}




	public function accessRules()

	{

		return array(

			array('allow',  // allow all users to perform 'index' and 'view' actions

				'actions'=>array('index','view'),

				'users'=>array('*'),

			),

			array('allow', // allow authenticated user to perform 'create' and 'update' actions

				'actions'=>array('create','update'),

				'users'=>array('@'),

			),

			array('allow', // allow admin user to perform 'admin' and 'delete' actions

				'actions'=>array('admin','delete'),

				'users'=>array('admin'),

			),

			array('deny',  // deny all users

				'users'=>array('*'),

			),

		);

	}




	public function actionView($id)

	{

		$this->render('view',array(

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

		));

	}




	public function actionCreate()

	{

		$model=new Zawodnik;




		if(isset($_POST['Zawodnik']))

		{

			$model->attributes=$_POST['Zawodnik'];

			if($model->save())

				$this->redirect(array('view','id'=>$model->id_zawodnika));

		}


		$this->render('create',array(

			'model'=>$model,

		));

	}




	public function actionUpdate($id)

	{

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

;


		if(isset($_POST['Zawodnik']))

		{

			$model->attributes=$_POST['Zawodnik'];

			if($model->save())

				$this->redirect(array('view','id'=>$model->id_zawodnika));

		}


		$this->render('update',array(

			'model'=>$model,

		));

	}




	public function actionDelete($id)

	{

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




		if(!isset($_GET['ajax']))

			$this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));

	}




	public function actionIndex()

	{

		$dataProvider=new CActiveDataProvider('Zawodnik');

		$this->render('index',array(

			'dataProvider'=>$dataProvider,

		));

	}




	public function actionAdmin()

	{

		$model=new Zawodnik('search');

		$model->unsetAttributes();  // clear any default values

		if(isset($_GET['Zawodnik']))

			$model->attributes=$_GET['Zawodnik'];


		$this->render('admin',array(

			'model'=>$model,

		));

	}




	public function loadModel($id)

	{

		$model=Zawodnik::model()->findByPk($id);

		if($model===null)

			throw new CHttpException(404,'The requested page does not exist.');

		return $model;

	}


	protected function performAjaxValidation($model)

	{

		if(isset($_POST['ajax']) && $_POST['ajax']==='zawodnik-form')

		{

			echo CActiveForm::validate($model);

			Yii::app()->end();

		}

	}

}



PHP notice

Trying to get property of non-object

C:\xampp\htdocs\stats\protected\views\zawodnik\_view.php(6)


1 

2 <div class="view">

3 

4 

5     <b>KLUB:</b>

6     <?php echo $data->test->nazwa; ?>

7     <br />

8 

9 </div>



aa jeszcze mam w Stack Trace na czerwono


  C:\xampp\htdocs\stats\protected\views\zawodnik\index.php(20): CBaseController->widget("zii.widgets.CListView", array("dataProvider" => CActiveDataProvider, "itemView" => "_view"))


15 <h1>Zawodniks</h1>

16 

17 <?php $this->widget('zii.widgets.CListView', array(

18     'dataProvider'=>$dataProvider,

19     'itemView'=>'_view',

20 )); ?>




  C:\xampp\htdocs\stats\protected\controllers\ZawodnikController.php(128): CController->render("index", array("dataProvider" => CActiveDataProvider))


123     public function actionIndex()

124     {

125         $dataProvider=new CActiveDataProvider('Zawodnik');

126         $this->render('index',array(

127             'dataProvider'=>$dataProvider,

128         ));

129     }

130 

131     /**

132      * Manages all models.

133      */




C:\xampp\htdocs\stats\index.php(13): CApplication->run()


08 defined('YII_DEBUG') or define('YII_DEBUG',true);

09 // specify how many levels of call stack should be shown in each log message

10 defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3);

11 

12 require_once($yii);

13 Yii::createWebApplication($config)->run();



W kontrolerze:




        public function actionIndex()

        {

                $dataProvider=new CActiveDataProvider('Zawodnik',array('criteria'=>array('with'=>array('klub'))));

                $this->render('index',array(

                        'dataProvider'=>$dataProvider,

                ));

        }



dalej to samo jest

spróbuj zmienić klub na test




array('with'=>array('test')



jak nie zadziała zrób var_dump() i podeślij co masz.




public function actionIndex()

        {

                $dataProvider=new CActiveDataProvider('Zawodnik',array('criteria'=>array('with'=>array('klub'))));


var_dump($dataProvider);

die();

                $this->render('index',array(

                        'dataProvider'=>$dataProvider,

                ));

        }



a sorry viktor zmieniłem modelu spowrotem na klub jak był jest to był błąd

"Relation "klub" is not defined in active record class "Zawodnik"."

a to zwraca mi var_dump z "poprawną" relacją


object(CActiveDataProvider)#27 (13) {

  ["modelClass"]=>

  string(<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/cool.gif' class='bbc_emoticon' alt='8)' /> "Zawodnik"

  ["model"]=>

  object(Zawodnik)#28 (11) {

    ["_new":"CActiveRecord":private]=>

    bool(false)

    ["_attributes":"CActiveRecord":private]=>

    array(0) {

    }

    ["_related":"CActiveRecord":private]=>

    array(0) {

    }

    ["_c":"CActiveRecord":private]=>

    NULL

    ["_pk":"CActiveRecord":private]=>

    NULL

    ["_alias":"CActiveRecord":private]=>

    string(1) "t"

    ["_errors":"CModel":private]=>

    array(0) {

    }

    ["_validators":"CModel":private]=>

    NULL

    ["_scenario":"CModel":private]=>

    string(0) ""

    ["_e":"CComponent":private]=>

    NULL

    ["_m":"CComponent":private]=>

    NULL

  }

  ["keyAttribute"]=>

  NULL

  ["_criteria":"CActiveDataProvider":private]=>

  object(CDbCriteria)#29 (17) {

    ["select"]=>

    string(1) "*"

    ["distinct"]=>

    bool(false)

    ["condition"]=>

    string(0) ""

    ["params"]=>

    array(0) {

    }

    ["limit"]=>

    int(-1)

    ["offset"]=>

    int(-1)

    ["order"]=>

    string(0) ""

    ["group"]=>

    string(0) ""

    ["join"]=>

    string(0) ""

    ["having"]=>

    string(0) ""

    ["with"]=>

    array(1) {

      [0]=>

      string(4) "klub"

    }

    ["alias"]=>

    NULL

    ["together"]=>

    NULL

    ["index"]=>

    NULL

    ["scopes"]=>

    NULL

    ["_e":"CComponent":private]=>

    NULL

    ["_m":"CComponent":private]=>

    NULL

  }

  ["_countCriteria":"CActiveDataProvider":private]=>

  NULL

  ["_id":"CDataProvider":private]=>

  string(<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/cool.gif' class='bbc_emoticon' alt='8)' /> "Zawodnik"

  ["_data":"CDataProvider":private]=>

  NULL

  ["_keys":"CDataProvider":private]=>

  NULL

  ["_totalItemCount":"CDataProvider":private]=>

  NULL

  ["_sort":"CDataProvider":private]=>

  NULL

  ["_pagination":"CDataProvider":private]=>

  NULL

  ["_e":"CComponent":private]=>

  NULL

  ["_m":"CComponent":private]=>

  NULL

}



pokaż relacje z modelu i action index




	public function relations()

    {

        return array(

            'klub'=>array(self::BELONGS_TO, 'Klub', array('przynaleznosc_klubowa'=>'id_klubu')),//array('fk'=>'pk')

        );

    }






   public function actionIndex()

        {

                $dataProvider=new CActiveDataProvider('Zawodnik',array('criteria'=>array('with'=>array('klub'))));

echo '<pre>';

var_dump($dataProvider);

die();

                $this->render('index',array(

                        'dataProvider'=>$dataProvider,

                ));

        }



no wygląda, że jest dobrze wywal tego var_dumpa i zobacz czy działa. Jak nie zobacz czy mozna pobrać dane, popatrzymy co zwraca zapytanie:




        public function actionIndex()

        {

                $dataProvider=new CActiveDataProvider('Zawodnik',array('criteria'=>array('with'=>array('klub'))));

                

                echo '<pre>';

                var_dump($dataProvider->getData());

                die();


                $this->render('index',array(

                        'dataProvider'=>$dataProvider,

                ));

        }



dodatkowo uruchom logowanie w main.php i zobacz jaki generuje się sql z joinem czy nie.

dalej notice mam

var_dump zwraca


array(2) {

  [0]=>

  object(Zawodnik)#63 (11) {

    ["_new":"CActiveRecord":private]=>

    bool(false)

    ["_attributes":"CActiveRecord":private]=>

    array(7) {

      ["id_zawodnika"]=>

      string(1) "1"

      ["imie"]=>

      string(<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/cool.gif' class='bbc_emoticon' alt='8)' /> "Bob"

      ["nazwisko"]=>

      string(<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/cool.gif' class='bbc_emoticon' alt='8)' /> "Budowniczy"

      ["wiek"]=>

      string(2) "23"

      ["waga"]=>

      string(2) "95"

      ["przynaleznosc_klubowa"]=>

      string(1) "1"

      ["opis_zawdonika"]=>

      string(10) "jaki? opis"

    }

    ["_related":"CActiveRecord":private]=>

    array(1) {

      ["klub"]=>

      object(Klub)#64 (11) {

        ["_new":"CActiveRecord":private]=>

        bool(false)

        ["_attributes":"CActiveRecord":private]=>

        array(4) {

          ["id_klubu"]=>

          string(1) "1"

          ["nazwa"]=>

          string(13) "budowlancy"

          ["opis_klubu"]=>

          string(0) ""

          ["id_trenera"]=>

          string(1) "0"

        }

        ["_related":"CActiveRecord":private]=>

        array(0) {

        }

        ["_c":"CActiveRecord":private]=>

        NULL

        ["_pk":"CActiveRecord":private]=>

        string(1) "1"

        ["_alias":"CActiveRecord":private]=>

        string(1) "t"

        ["_errors":"CModel":private]=>

        array(0) {

        }

        ["_validators":"CModel":private]=>

        NULL

        ["_scenario":"CModel":private]=>

        string(6) "update"

        ["_e":"CComponent":private]=>

        NULL

        ["_m":"CComponent":private]=>

        NULL

      }

    }

    ["_c":"CActiveRecord":private]=>

    NULL

    ["_pk":"CActiveRecord":private]=>

    string(1) "1"

    ["_alias":"CActiveRecord":private]=>

    string(1) "t"

    ["_errors":"CModel":private]=>

    array(0) {

    }

    ["_validators":"CModel":private]=>

    NULL

    ["_scenario":"CModel":private]=>

    string(6) "update"

    ["_e":"CComponent":private]=>

    NULL

    ["_m":"CComponent":private]=>

    NULL

  }

  [1]=>

  object(Zawodnik)#65 (11) {

    ["_new":"CActiveRecord":private]=>

    bool(false)

    ["_attributes":"CActiveRecord":private]=>

    array(7) {

      ["id_zawodnika"]=>

      string(1) "3"

      ["imie"]=>

      string(4) "opip"

      ["nazwisko"]=>

      string(5) "iopio"

      ["wiek"]=>

      string(1) "0"

      ["waga"]=>

      string(1) "0"

      ["przynaleznosc_klubowa"]=>

      string(1) "0"

      ["opis_zawdonika"]=>

      string(4) "0000"

    }

    ["_related":"CActiveRecord":private]=>

    array(1) {

      ["klub"]=>

      NULL

    }

    ["_c":"CActiveRecord":private]=>

    NULL

    ["_pk":"CActiveRecord":private]=>

    string(1) "3"

    ["_alias":"CActiveRecord":private]=>

    string(1) "t"

    ["_errors":"CModel":private]=>

    array(0) {

    }

    ["_validators":"CModel":private]=>

    NULL

    ["_scenario":"CModel":private]=>

    string(6) "update"

    ["_e":"CComponent":private]=>

    NULL

    ["_m":"CComponent":private]=>

    NULL

  }

}



co masz na myśli z tym logowaniem w main.php

wywal z bazy danych zawodnika o id_zawodnika=3 albo wpisz id_klubu do którego należy bo nie jest ustawione (w końcu chcesz żeby były relacje). Sprawdź i daj znać.

LOGOWANIE w main.php

powinienś mieć sekcje ‘log’, odkomentuj CWebLogRoute i będziesz miał w oknie przeglądarki log z działania aplikacji.




        'log' => array(

            'class' => 'CLogRouter',

            'routes' => array(


                array(

                    'class' => 'CFileLogRoute',

                    'levels' => 'error, warning',

                ),


                /*

                 array(

                 'class'=>'CWebLogRoute',

                 ),

                 */


            ),