Yii Framework Forum: Ricercare per una chiave esterna? - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Ricercare per una chiave esterna? Devo ricercare in un campo testuale di una chiave esterna ... Rate Topic: ***** 1 Votes

#1 User is offline   sensorario 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 1,986
  • Joined: 07-September 10
  • Location:Cesena (Italy)

Posted 23 March 2011 - 12:13 PM

Ho fatto diversi tentativi e nessuno è andato a buon fine. Ho una tabella che "attinge" da tabelle esterne. Quando metto in un datagrid dei campi esterni, non compare più il campo di ricerca. Vorrei, invece, che rimanesse. Come posso farlo? Non ho trovato link su yii, forse non ho cercato bene. Sono anche sicuro di aver letto qualche cosa del genere in questo forum. Chi mi sa aiutare a cercarlo?
0

#2 User is offline   zaccaria 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 2,232
  • Joined: 04-October 09
  • Location:Moscow

Posted 24 March 2011 - 09:00 AM

Per ricercare su campi esterni devi:

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.
1

#3 User is offline   sensorario 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 1,986
  • Joined: 07-September 10
  • Location:Cesena (Italy)

Posted 05 April 2011 - 06:02 AM

Non conosco la sintassi corretta del punto "aggiungere i criteria nella funzione search (sia with->toghether che le condition)" Per il resto ho fatto tutto. Mi potresti dare un ultimo piccolo help?
0

#4 User is offline   sensorario 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 1,986
  • Joined: 07-September 10
  • Location:Cesena (Italy)

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
0

#5 User is offline   sensorario 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 1,986
  • Joined: 07-September 10
  • Location:Cesena (Italy)

Posted 05 April 2011 - 07:22 AM

Non demordo: ora funziona (nel senso che no mi da errori... devo solo mettere la textbox dentro al CDataGrid
      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,
          ));
      }

0

#6 User is offline   sensorario 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 1,986
  • Joined: 07-September 10
  • Location:Cesena (Italy)

Posted 05 April 2011 - 08:17 AM

Ce l'ho fatta!!!
(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!
0

#7 User is offline   sensorario 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 1,986
  • Joined: 07-September 10
  • Location:Cesena (Italy)

Posted 05 April 2011 - 08:53 AM

Problema! citta.nome e paesi.nome entrano in conflitto.
          $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)


0

#8 User is offline   nickcv 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 154
  • Joined: 23-November 10

Posted 05 April 2011 - 04:53 PM

semplicemente l'errore viene dato perchè nel where gli dici di controllare nome, il problema sta che in entrambe le tabelle c'è una colonna nome, quindi il dato è ambiguo, quindi devi specificare quello di quale tabella
sometimes it's just like teaching pigs how to fly

Posted Image
Posted Image looking for some invite keys? welcome on B4K!
0

#9 User is offline   sensorario 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 1,986
  • Joined: 07-September 10
  • Location:Cesena (Italy)

Posted 05 April 2011 - 05:27 PM

Che poi è quello che ho scritto io. Ho due campi nome. Come faccio a dare loro un alias?
0

#10 User is offline   nickcv 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 154
  • Joined: 23-November 10

Posted 05 April 2011 - 05:34 PM

yii in teoria lo fa in automatico.
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.
sometimes it's just like teaching pigs how to fly

Posted Image
Posted Image looking for some invite keys? welcome on B4K!
1

#11 User is offline   nickcv 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 154
  • Joined: 23-November 10

Posted 05 April 2011 - 05:37 PM

inoltre usare un alias tipo relNomeModel rende più semplice la lettura quando estrai i dati dall'oggetto.

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.
sometimes it's just like teaching pigs how to fly

Posted Image
Posted Image looking for some invite keys? welcome on B4K!
0

#12 User is offline   sensorario 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 1,986
  • Joined: 07-September 10
  • Location:Cesena (Italy)

Posted 06 April 2011 - 01:27 AM

View Postnickcv, on 05 April 2011 - 05:34 PM, said:

yii in teoria lo fa in automatico.
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?
0

#13 User is offline   sensorario 

  • Elite Member
  • Yii
  • Group: Moderators
  • Posts: 1,986
  • Joined: 07-September 10
  • Location:Cesena (Italy)

Posted 06 April 2011 - 01:46 AM

Ho risolto:
      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.
0

#14 User is offline   nickcv 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 154
  • Joined: 23-November 10

Posted 06 April 2011 - 01:56 AM

le impostazioni del debug sono nel file config della tua applicazione yii, comunque non c'è bisogno al momento, riguardando la tua schermata d'errore si può benissimo leggere la query.

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 ^^
sometimes it's just like teaching pigs how to fly

Posted Image
Posted Image looking for some invite keys? welcome on B4K!
0

#15 User is offline   nickcv 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 154
  • Joined: 23-November 10

Posted 06 April 2011 - 02:46 AM

nessun problema sensorario :P

è 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!
sometimes it's just like teaching pigs how to fly

Posted Image
Posted Image looking for some invite keys? welcome on B4K!
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users