Relazioni interne

Ciao ragazzi,

ho una tabella chiamata tab1 al suo interno i campi id,label,id_parent e il relativo model.

Mediante il widget ‘CDetailView’ sto visualizzando i dati di questa tabella.

il problema è il seguente:

invece di id_parent voglio visualizzare nel componente il campo label associato

se utilizzo una chiave interna , quindi id_parent collegata ad id, si genera un loop infinito quando il widget estrae l’active record.

Avete qualche soluzione?

Consideriamo che il nome del tuo Model sia [b]Tab1.

[/b]Modifica il file della view con il CDetailView in questo modo:




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

  'data'=>$model,

  'attributes'=>array(

  'id',

  'label', 

  array(

  'label'=>'parent ID',

  'type'=>'raw',

  'value'=>Tab1::Model()->findByPk($model->parent_id)->label,

  ),

  ),

 ));



Spero che vada bene.

In questo caso però non vai a fare una query per ogni riga presente? Non c’è qualche modo più performante?

Non ti genera un loop infinito.

Usa una relazione has one, e fai la query con Tab1::model()->with(‘parent’)->findAll();

Funziona. Se anche avessi 2 record che si puntano a vicenda, la query estrae solo il primo livello di parentela e non va oltre.

@dchan

non funziona. quando il campo id_parent è settato a 0, quindi mi genera un errore

Trying to get property of non-object

@zaccaria

ok penso di aver capito cosa intendi ci provo e ti faccio sapere

ok non funziona. quando id_parent = 0 , quindi non è collegato a niente , mi genera come errore

Trying to get property of non-object

al momento ho risolto definendo un metodo statico all’interno del mio model. Un metodo di questo tipo




static function findParent($idParent)

  {

	

	$criteria = new CDbCriteria();

	$criteria->condition = "id_menu=$idParent";

	$rec = Menu::model()->find($criteria);

	if(!empty($rec->label))

	 return($rec->label);

	else

	  return "";

  }



grazie a tutti

non farlo statico:


function findParent()

  {

        

        $criteria = new CDbCriteria();

        $criteria->condition = "id_menu=$this->id_parent";

        $rec = Menu::model()->find($criteria);

        if(!empty($rec->label))

         return($rec->label);

        else

          return "";

  }

e poi non ti serve fare queste cose, basta che imposti la relazione


'parent' => array(self::BELONGS_TO, 'Menu', 'parent_id'),



e puoi chiamare il parent con:


$this->parent



Inoltre e’ normale che dia eccezione se non c’e’ il record, puoi risolvere cosi’:


'value'=>($this->parent)?$this->parent->label:''



Le relations sono un po’ ostiche all’inizio, dai retta a me: imposta le foreign key correttamente del database e lascia a Gii il compito di generare le relations, vedrai che diventa tutto molto piu’ abbordabile.

ciao zaccaria,

alla fine ho fatto pratica con le relazioni.

grazie per la risposta.

lode a zaccaria