Ricercare per una chiave esterna? Devo ricercare in un campo testuale di una chiave esterna ...
#1
Posted 23 March 2011 - 12:13 PM
#2
Posted 24 March 2011 - 09:00 AM
aggiungere le proprieta' al model, per poter raccogliere i dati
marcare queste proprieta' come safe on search nelle rules
aggiungere i criteria nella funzione search (sia with->toghether che le condition)
Una volta fatto questo, puoi rimettere le textbox nel datagrid con la proprita' filter di cgridView.
#3
Posted 05 April 2011 - 06:02 AM
#4
Posted 05 April 2011 - 07:10 AM
public function search() {
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria = new CDbCriteria;
$criteria->compare('id', $this->id);
$criteria->compare('nome', $this->nome, true);
$criteria->compare('citta', $this->citta, true);
$criteria->condition = 'cittadina = citta';
return new CActiveDataProvider(get_class($this), array(
'criteria' => $criteria,
));
}Ho creato una tabella paesi(id,nome,citta) citta corrisponde all'id di citta(id,nome).
Il with come lo metto? Scusami ma ho un lapsus
#5
Posted 05 April 2011 - 07:22 AM
public function search() {
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria = new CDbCriteria;
$criteria->compare('id', $this->id);
$criteria->compare('nome', $this->nome, true);
$criteria->condition = 'cittadina.id = citta';
$criteria->with = array('cittadina');
return new CActiveDataProvider(get_class($this), array(
'criteria' => $criteria,
));
}
#6
Posted 05 April 2011 - 08:17 AM
(ho trovato un post di qualche tempo fa di zaccaria e mdomba nel forum inglese)
Così ho saputo correggere il mio codice in questo modo:
MODEL:
nel model si deve prima creare la relazione e poi aggiungerla nelle regole
public function rules() {
return array(
array('nome, citta', 'required'),
array('citta', 'numerical', 'integerOnly' => true),
array('nome', 'length', 'max' => 50),
array('id, nome, citta, cittadina', 'safe', 'on' => 'search'),
);
}
/**
* @return array relational rules.
*/
public function relations() {
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'cittadina' => array(self::BELONGS_TO, 'Citta', 'citta'),
);
}VIEW:
Nel CGridView bisogna aggiungere un array ed indicare il nome della relazione, il filtro da usare ed il valore.
<?php
$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'paesi-grid',
'dataProvider' => $model->search(),
'filter' => $model,
'columns' => array(
'id',
'nome',
array(
'name' => 'cittadina',
'filter' => CHtml::activeTextField($model, 'cittadina'),
'value' => '$data->cittadina->nome',
),
array(
'class' => 'CButtonColumn',
),
),
));
?>CONTROLLER:
Infine nel controller bisogna fare si che la ricerca vada a ficcare il naso nella tabella esterna.
public function search() {
$criteria = new CDbCriteria;
$criteria->compare('nome', $this->nome, true);
$criteria->compare('cittadina.nome', $this->cittadina, true);
$criteria->join = 'join citta on citta.id = t.citta';
$criteria->with = array('cittadina');
return new CActiveDataProvider(get_class($this), array(
'criteria' => $criteria,
));
}Per completare questo post, ci aggiungo anche il Dump del mio database nel caso qualcuno volesse provare questo esempio per conto proprio come ho fatto io:
CREATE TABLE IF NOT EXISTS `citta` ( `id` int(11) NOT NULL AUTO_INCREMENT, `nome` varchar(50) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ; INSERT INTO `citta` (`id`, `nome`) VALUES (1, 'Cesena'), (2, 'Roma'); CREATE TABLE IF NOT EXISTS `paesi` ( `id` int(11) NOT NULL AUTO_INCREMENT, `nome` varchar(50) NOT NULL, `citta` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ; INSERT INTO `paesi` (`id`, `nome`, `citta`) VALUES (1, 'San Carlo', 1), (2, 'San Vittore', 1), (3, 'Trastevere', 2);
TESTATO E FUNZIONANTE!
#7
Posted 05 April 2011 - 08:53 AM
$criteria->compare('nome', $this->nome, true);
$criteria->compare('cittadina.nome', $this->cittadina, true);Se cerco per città funziona tutto correttamente. Se però cerco per nome ottengo un errorone brutto brutto =(. Allego l'errore e prego.
Per inciso: l'errore sta nel fatto che la query è del tipo select paesi.nome, citta.nome. Trovandosi con due nomi uguale va in errore. Suppongo sia lo stesso problema riscontrato su chive che ho segnalato come bug e che dovrebbe essere corretto nella prossima versione.
Attached File(s)
-
screenshot3.png (127.56K)
Number of downloads: 12
#8
Posted 05 April 2011 - 04:53 PM
#9
Posted 05 April 2011 - 05:27 PM
#10
Posted 05 April 2011 - 05:34 PM
nel metodo relations del model assegni un alias a ciascuna relazione (di solito io uso relNomeModel per evitare possibili eventuali conflitti con nomi di colonne, quindi se ho una tabella user che ha relazioni con una tabella groups chiamo la relazione relGroups)
se stai usando CDbCriteria usa la dot notation quando chiami il nome del campo (relGroups.nome)
se devi chiamare il dato della tabella originale yii usa come alias t (o almeno così faceva nella versione 1.1.5 quando stavo impazzendo per capire che stava facendo)
se qualcosa non ti torna o hai dubbi fai mostrare al debug le query così vedi quali alias yii genera in automatico.
#11
Posted 05 April 2011 - 05:37 PM
se ad esempio vedi una cosa del tipo $user->relGroup->name capisci subito senza dovertelo ricordare che il dato name che stai estraendo si trova in realtà in un altra tabella.
#12
Posted 06 April 2011 - 01:27 AM
nickcv, on 05 April 2011 - 05:34 PM, said:
nel metodo relations del model assegni un alias a ciascuna relazione (di solito io uso relNomeModel per evitare possibili eventuali conflitti con nomi di colonne, quindi se ho una tabella user che ha relazioni con una tabella groups chiamo la relazione relGroups)
se stai usando CDbCriteria usa la dot notation quando chiami il nome del campo (relGroups.nome)
se devi chiamare il dato della tabella originale yii usa come alias t (o almeno così faceva nella versione 1.1.5 quando stavo impazzendo per capire che stava facendo)
se qualcosa non ti torna o hai dubbi fai mostrare al debug le query così vedi quali alias yii genera in automatico.
Come faccio a mostrare al debug le query così vedo quali alias yii ha generato in automatico?
#13
Posted 06 April 2011 - 01:46 AM
public function search() {
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria = new CDbCriteria;
$criteria->compare('t.nome', $this->nome, true);
$criteria->compare('cittadina.nome', $this->cittadina, true);
$criteria->join = 'join citta on citta.id = t.citta';
$criteria->with = array('cittadina');
return new CActiveDataProvider(get_class($this), array(
'criteria' => $criteria,
));
}ovvero:
$criteria->compare('t.nome', $this->nome, true);L'informazione di nickcv, quella di usare la dot notation era corretta solo che non specificava dove e come andava usata. Spero non abbia nulla in contrario se riposto la soluzione.
#14
Posted 06 April 2011 - 01:56 AM
come giustamente ricordavo l'alias della prima tabella è t mentre quella della seconda tabella in questo caso è citta
scusa la risposta frettolosa ma sto fuggendo per arrivare in ufficio ^^
#15
Posted 06 April 2011 - 02:46 AM
è che a volte sono un pò di fretta e mi rendo conto che do per scontate alcune conoscenze pregresse ^^
sono contento comunque che hai risolto!

Help
















