Relazione Molti A Molti

Dovrei realizzare una ricerca con relazione molti a molti, tramite il modulo gii ho creato modelli,viste,controller;nella form di ricerca ho un campo nome e mi viene filtrata la tabella negozi,ora al form vorrei aggiungere un campo marca, dove per marca ho creato una tabella, in quanto più negozi possono avere più marche e più marche posso avere più negozi,quindi come inserisco la marca nel campo input della form…dovrei avere tutti i negozi che sono associati a quella marca,come posso gestire la cosa

Inserire nel model della tabella negozi


public function relations(){// MANY_MANY}

nella funzione search del model negozi ho questo


public function search()

	{

		// @todo Please modify the following code to remove attributes that should not be searched.


		$criteria=new CDbCriteria;

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

               

       

		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

                        

		));

	}

nel controller ho questo…,dovrei modicare intercettando l’input del campo marche(che aggiungerò alla mia form)…e farli eseguire la relazione


public function actionIndex()

	{

		

        $model=new Attivita('search');// carica funzione search

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

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

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


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

			'model'=>$model,

                        

		));

Devi aggiungere una proprieta’ al modello marche, per esempio nome_marca, e renderla safe in search.

Poi nella search fai:




        public function search()

        {

                // @todo Please modify the following code to remove attributes that should not be searched.


                $criteria=new CDbCriteria;

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

               if ($this->nome_marca){

                   $criteria->with= array('marche');

                   $criteria->toghether= true;

                   $criteria->compare('marche.nome', $this->nome_marca)

               }

               

       

                return new CActiveDataProvider($this, array(

                        'criteria'=>$criteria,

                        

                ));

        }



Una alternativa e’ non fare la join e scrivere la condizione a mano:




                   $criteria->addCondition('id in (SELECT attivita_id FROM attivita2marche WHERE marche_id IN (SELECT id FROM marche WHERE nome like :nome_marche))');

                   $criteria->params[':nome_marche']='%'.$this->nome_marche.'%'




Grazie per la risposta, ho studiato il tuo consiglio e consulato la documentazione delle relazione many_to_many.

Ecco il mio codice

Model marche (ho aggiunto la proprietà nome_marca…, e impostato la relazione many_to many)




public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

			array('attivita_id', 'required'),

			array('attivita_id', 'length', 'max'=>10),

			array('nome, categoria, gruppo', 'length', 'max'=>255),

			array('descrizione', 'safe'),

			// The following rule is used by search().

			// @todo Please remove those attributes that should not be searched.

			array('id, attivita_id, nome, categoria, gruppo, descrizione','nome_marca', '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(

			'attivitas' => array(self::MANY_MANY, 'Attivita', 'attivita_marche(marche_id, attivita_id)'),

                );

			

	}



nel model attivita




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(

			'marches' => array(self::MANY_MANY, 'Marche', 'attivita_marche(marche_id, utenti_id)'),

			

			

		);

	}


public function search()

	{

		// @todo ricerca per nome attività e per marca con relazione Many_To_Many


		$criteria=new CDbCriteria;

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

                if ($this->nome_marca){

                   $criteria->with= array('marche');

                   $criteria->toghether= true;

                   $criteria->compare('marche.nome', $this->nome_marca);

               }

       

		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

                        

		));

	}







il form invece




<div class="wide form">


<?php $form=$this->beginWidget('CActiveForm', array(

	'action'=>Yii::app()->createUrl('attivita/index'),

	'method'=>'get',

)); ?>

	<div class="row">

		<?php echo $form->label($model,'nome'); ?>

		<?php echo $form->textField($model,'nome',array('size'=>20,'maxlength'=>255)); ?>

	</div>

	<div class="row">

		<?php echo $form->label($model,'nome_marca'); ?>

		<?php echo $form->textField($model,'nome_marca',array('size'=>20,'maxlength'=>255)); ?>

	</div>

    

	<div class="row buttons">

		<?php echo CHtml::submitButton('Search'); ?>

	</div>


<?php $this->endWidget(); ?>



Controller




public function actionIndex()

	{

		

        $model=new Attivita('search');// carica funzione search

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

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

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


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

			'model'=>$model,

                        

		));

            

     

            

            

            

	}



però mi dice proprietà nome_marca non defininta

pardon non avevo aggiunto la proprietà al model Marche

public $nome_marca;

ma da lo stesso errore

Dovrebbe funzionare, probabilmente hai un errore di battitura o hai usato un $this al posto di $model, serve un po’ di debug.

A occhio mi sembra che l’unico errore sia


                   $criteria->with= array('marche');

                   $criteria->toghether= true;

                   $criteria->compare('marche.nome', $this->nome_marca);

la tua relazione si chiama marches e non marche.

ho fatto un pò di debug, aggiungendo la proprietà $nome_marca al modello marche mi da il seguente errore


include(nome_marca.php): failed to open stream: No such file or directory

se invece aggiungo questa proprietà al modello attivita(che è quello in cui c’è la funzione search)…funziona ma quando faccio la ricerca tramite, sia con il campo nome che con quello marca da il seguente errore




include(nome_marca.php): failed to open stream: No such file or directory



ho corretto la search




public function search()

	{

		// @todo ricerca per nome attività e per marca con relazione Many_To_Many


		$criteria=new CDbCriteria;

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

                	if ($this->nome_marca){

                   $criteria->with= array('marches');

                   $criteria->toghether= true;

                   $criteria->compare('marches.nome', $this->nome_marca);

               }


                 

		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

                        

		));

	}



La proprieta’ va aggiunta al modello un cui c’e’ la search.

L’errore che hai e’ molto strano, probabilmente stai mettendo la public $nome_marche in un posto sbagliato.

infatti l’ho messa nel modello della search


<?php


/**

 * This is the model class for table "attivita".

 *

 * The followings are the available columns in table 'attivita':

 * @property string $id

 * @property string $eventi_id

 * @property string $nome

 * @property string $descrizione

 * @property string $indirizzo

 * @property string $titolo

 * @property string $coordinate

 * @property string $image

 * @property string $categoria

 * @property string $username

 * @property string $psw

 * @property string $nome_marca

 * The followings are the available model relations:

 * @property Marche[] $marches

 * @property Offerte[] $offertes

 * @property Parcheggi[] $parcheggis

 */

class Attivita extends CActiveRecord

{


	public $nome_marca;

	/**

	 * @return string the associated database table name

	 */

	public function tableName()

	{

		return 'attivita';

	}


	/**

	 * @return array validation rules for model attributes.

	 */

	public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

			array('eventi_id', 'required'),

			array('eventi_id', 'length', 'max'=>10),

			array('nome, titolo, coordinate, categoria, username, psw', 'length', 'max'=>255),

			array('descrizione, indirizzo, image', 'safe'),

			// The following rule is used by search().

			// @todo Please remove those attributes that should not be searched.

			array('id, eventi_id, nome, descrizione, indirizzo, titolo, coordinate, image, categoria, username, psw','nome_marca', '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(

			'marches' => array(self::MANY_MANY, 'Marche', 'attivita_marche(marche_id, utenti_id)'),

			

			'offertes' => array(self::HAS_MANY, 'Offerte', 'attivita_id'),

			'parcheggis' => array(self::HAS_MANY, 'Parcheggi', 'attivita_id'),

		);

	}


	/**

	 * @return array customized attribute labels (name=>label)

	 */

	public function attributeLabels()

	{

		return array(

			'id' => 'ID',

			'eventi_id' => 'Eventi',

			'nome' => 'Nome',

			'descrizione' => 'Descrizione',

			'indirizzo' => 'Indirizzo',

			'titolo' => 'Titolo',

			'coordinate' => 'Coordinate',

			'image' => 'Image',

			'categoria' => 'Categoria',

			'username' => 'Username',

			'psw' => 'Psw',

			'nome_marca' => 'nome_marca',

		);

	}


	/**

	 * Retrieves a list of models based on the current search/filter conditions.

	 *

	 * Typical usecase:

	 * - Initialize the model fields with values from filter form.

	 * - Execute this method to get CActiveDataProvider instance which will filter

	 * models according to data in model fields.

	 * - Pass data provider to CGridView, CListView or any similar widget.

	 *

	 * @return CActiveDataProvider the data provider that can return the models

	 * based on the search/filter conditions.

	 */

	public function search()

	{

		// @todo ricerca per nome attività e per marca con relazione Many_To_Many


		$criteria=new CDbCriteria;

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

                	if ($this->nome_marca){

                   $criteria->with= array('marches');

                   $criteria->toghether= true;

                   $criteria->compare('marches.nome', $this->nome_marca);

               }


                 

		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

                        

		));

	}


	/**

	 * Returns the static model of the specified AR class.

	 * Please note that you should have this exact method in all your CActiveRecord descendants!

	 * @param string $className active record class name.

	 * @return Attivita the static model class

	 */

        

        public function categoria(){

               /* $criteria=new CDbCriteria;

		$criteria->compare('categoria','sportiva');

                

		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

		));*/

        }




        public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}

}



E l’errore a che riga di codice de lo da?


PHP warning


include(nome_marca.php): failed to open stream: No such file or directory


C:\xampp\htdocs\sites\yii\framework\YiiBase.php(421)


409                         {

410                             include($classFile);

411                             if(YII_DEBUG && basename(realpath($classFile))!==$className.'.php')

412                                 throw new CException(Yii::t('yii','Class name "{class}" does not match class file "{file}".', array(

413                                     '{class}'=>$className,

414                                     '{file}'=>$classFile,

415                                 )));

416                             break;

417                         }

418                     }

419                 }

420                 else

421                     include($className.'.php');

422             }

423             else  // class name with namespace in PHP 5.3

424             {

425                 $namespace=str_replace('\\','.',ltrim($className,'\\'));

426                 if(($path=self::getPathOfAlias($namespace))!==false)

427                     include($path.'.php');

428                 else

429                     return false;

430             }

431             return class_exists($className,false) || interface_exists($className,false);

432         }

433         return true;

Stack Trace

#0	

+  C:\xampp\htdocs\sites\yii\framework\YiiBase.php(421): YiiBase::autoload()

#1	

+  C:\xampp\htdocs\sites\yii\framework\YiiBase.php(296): YiiBase::autoload("nome_marca")

#2	

+  C:\xampp\htdocs\sites\yii\framework\validators\CValidator.php(186): YiiBase::import("nome_marca", true)

#3	

+  C:\xampp\htdocs\sites\yii\framework\base\CModel.php(287): CValidator::createValidator("nome_marca", Attivita, "descrizione, indirizzo, image", array("safe"))

#4	

+  C:\xampp\htdocs\sites\yii\framework\base\CModel.php(260): CModel->createValidators()

#5	

+  C:\xampp\htdocs\sites\yii\framework\base\CModel.php(547): CModel->getValidators()

#6	

+  C:\xampp\htdocs\sites\yii\framework\base\CModel.php(468): CModel->getSafeAttributeNames()

#7	

+  C:\xampp\htdocs\sites\yii\framework\base\CComponent.php(152): CModel->setAttributes(array("nome" => "", "nome_marca" => ""))

#8	

+  C:\xampp\htdocs\sites\yii\framework\db\ar\CActiveRecord.php(161): CComponent->__set("attributes", array("nome" => "", "nome_marca" => ""))

#9	

–  C:\xampp\htdocs\sites\Macerata2\protected\controllers\AttivitaController.php(110): CActiveRecord->__set("attributes", array("nome" => "", "nome_marca" => ""))

105     {

106         

107         $model=new Attivita('search');// carica funzione search

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

109         if(isset($_GET['Attivita']))

110             $model->attributes=$_GET['Attivita'];

111 

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

113             'model'=>$model,

114                         

115         ));

#10	

+  C:\xampp\htdocs\sites\yii\framework\web\actions\CInlineAction.php(49): AttivitaController->actionIndex()

#11	

+  C:\xampp\htdocs\sites\yii\framework\web\CController.php(308): CInlineAction->runWithParams(array("Attivita" => array("nome" => "", "nome_marca" => ""), "yt0" => "Search"))

#12	

+  C:\xampp\htdocs\sites\yii\framework\web\filters\CFilterChain.php(133): CController->runAction(CInlineAction)

#13	

+  C:\xampp\htdocs\sites\yii\framework\web\filters\CFilter.php(40): CFilterChain->run()

#14	

+  C:\xampp\htdocs\sites\yii\framework\web\CController.php(1145): CFilter->filter(CFilterChain)

#15	

+  C:\xampp\htdocs\sites\yii\framework\web\filters\CInlineFilter.php(58): CController->filterAccessControl(CFilterChain)

#16	

+  C:\xampp\htdocs\sites\yii\framework\web\filters\CFilterChain.php(130): CInlineFilter->filter(CFilterChain)

#17	

+  C:\xampp\htdocs\sites\yii\framework\web\CController.php(291): CFilterChain->run()

#18	

+  C:\xampp\htdocs\sites\yii\framework\web\CController.php(265): CController->runActionWithFilters(CInlineAction, array("accessControl", "postOnly + delete"))

#19	

+  C:\xampp\htdocs\sites\yii\framework\web\CWebApplication.php(282): CController->run("index")

#20	

+  C:\xampp\htdocs\sites\yii\framework\web\CWebApplication.php(141): CWebApplication->runController("attivita/index")

#21	

+  C:\xampp\htdocs\sites\yii\framework\base\CApplication.php(180): CWebApplication->processRequest()

#22	

–  C:\xampp\htdocs\sites\Macerata2\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();

L’errore e’ nelle rules, come sono scritte?


+  C:\xampp\htdocs\sites\yii\framework\base\CModel.php(287): CValidator::createValidator("nome_marca", Attivita, "descrizione, indirizzo, image", array("safe"))

sono scritte male:




array('id, eventi_id, nome, descrizione, indirizzo, titolo, coordinate, image, categoria, username, psw','nome_marca', 'safe', 'on'=>'search'),




nome_marca viene visto come validatore.

deve essere così:




  array('id, eventi_id, nome, descrizione, indirizzo, titolo, coordinate, image, categoria, username, psw, nome_marca', 'safe', 'on'=>'search'),




scusate se rispondo oggi ma ero influenzato, ho corretto le rules sul model dove c’è la search, ma il risultato rimane

Model


<?php


/**

 * This is the model class for table "attivita".

 *

 * The followings are the available columns in table 'attivita':

 * @property string $id

 * @property string $eventi_id

 * @property string $nome

 * @property string $descrizione

 * @property string $indirizzo

 * @property string $titolo

 * @property string $coordinate

 * @property string $image

 * @property string $categoria

 * @property string $username

 * @property string $psw

 * @property string $nome_marca

 * The followings are the available model relations:

 * @property Marche[] $marches

 * @property Offerte[] $offertes

 * @property Parcheggi[] $parcheggis

 */

class Attivita extends CActiveRecord

{


	public $nome_marca;

	/**

	 * @return string the associated database table name

	 */

	public function tableName()

	{

		return 'attivita';

	}


	/**

	 * @return array validation rules for model attributes.

	 */

	public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

			array('eventi_id', 'required'),

			array('eventi_id', 'length', 'max'=>10),

			array('nome, titolo, coordinate, categoria, username, psw', 'length', 'max'=>255),

			array('descrizione, indirizzo, image','nome_marca','safe'),

			// The following rule is used by search().

			// @todo Please remove those attributes that should not be searched.

			array('id, eventi_id, nome, descrizione, indirizzo, titolo, coordinate, image, categoria, username, psw, nome_marca', '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(

			'marches' => array(self::MANY_MANY, 'Marche', 'attivita_marche(marche_id, utenti_id)'),

			

			'offertes' => array(self::HAS_MANY, 'Offerte', 'attivita_id'),

			'parcheggis' => array(self::HAS_MANY, 'Parcheggi', 'attivita_id'),

		);

	}


	/**

	 * @return array customized attribute labels (name=>label)

	 */

	public function attributeLabels()

	{

		return array(

			'id' => 'ID',

			'eventi_id' => 'Eventi',

			'nome' => 'Nome',

			'descrizione' => 'Descrizione',

			'indirizzo' => 'Indirizzo',

			'titolo' => 'Titolo',

			'coordinate' => 'Coordinate',

			'image' => 'Image',

			'categoria' => 'Categoria',

			'username' => 'Username',

			'psw' => 'Psw',

			'nome_marca' => 'nome_marca',

		);

	}


	/**

	 * Retrieves a list of models based on the current search/filter conditions.

	 *

	 * Typical usecase:

	 * - Initialize the model fields with values from filter form.

	 * - Execute this method to get CActiveDataProvider instance which will filter

	 * models according to data in model fields.

	 * - Pass data provider to CGridView, CListView or any similar widget.

	 *

	 * @return CActiveDataProvider the data provider that can return the models

	 * based on the search/filter conditions.

	 */

	public function search()

	{




		// @todo ricerca per nome attività e per marca con relazione Many_To_Many


		$criteria=new CDbCriteria;

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

                	if ($this->nome_marca){

                   $criteria->with= array('marches');

                   $criteria->toghether= true;

                   $criteria->compare('marches.nome_marca', $this->nome_marca,true);

               }


                 

		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

                        

		));

	}


	/**

	 * Returns the static model of the specified AR class.

	 * Please note that you should have this exact method in all your CActiveRecord descendants!

	 * @param string $className active record class name.

	 * @return Attivita the static model class

	 */

        

        public function categoria(){

               /* $criteria=new CDbCriteria;

		$criteria->compare('categoria','sportiva');

                

		return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

		));*/

        }




        public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}

}



errore


PHP warning


include(nome_marca.php): failed to open stream: No such file or directory


C:\xampp\htdocs\sites\yii\framework\YiiBase.php(421)


409                         {

410                             include($classFile);

411                             if(YII_DEBUG && basename(realpath($classFile))!==$className.'.php')

412                                 throw new CException(Yii::t('yii','Class name "{class}" does not match class file "{file}".', array(

413                                     '{class}'=>$className,

414                                     '{file}'=>$classFile,

415                                 )));

416                             break;

417                         }

418                     }

419                 }

420                 else

421                     include($className.'.php');

422             }

423             else  // class name with namespace in PHP 5.3

424             {

425                 $namespace=str_replace('\\','.',ltrim($className,'\\'));

426                 if(($path=self::getPathOfAlias($namespace))!==false)

427                     include($path.'.php');

428                 else

429                     return false;

430             }

431             return class_exists($className,false) || interface_exists($className,false);

432         }

433         return true;

Stack Trace

#0	

+  C:\xampp\htdocs\sites\yii\framework\YiiBase.php(421): YiiBase::autoload()

#1	

+  C:\xampp\htdocs\sites\yii\framework\YiiBase.php(296): YiiBase::autoload("nome_marca")

#2	

+  C:\xampp\htdocs\sites\yii\framework\validators\CValidator.php(186): YiiBase::import("nome_marca", true)

#3	

+  C:\xampp\htdocs\sites\yii\framework\base\CModel.php(287): CValidator::createValidator("nome_marca", Attivita, "descrizione, indirizzo, image", array("safe"))

#4	

+  C:\xampp\htdocs\sites\yii\framework\base\CModel.php(260): CModel->createValidators()

#5	

+  C:\xampp\htdocs\sites\yii\framework\base\CModel.php(547): CModel->getValidators()

#6	

+  C:\xampp\htdocs\sites\yii\framework\base\CModel.php(468): CModel->getSafeAttributeNames()

#7	

+  C:\xampp\htdocs\sites\yii\framework\base\CComponent.php(152): CModel->setAttributes(array("nome" => "", "nome_marca" => "And"))

#8	

+  C:\xampp\htdocs\sites\yii\framework\db\ar\CActiveRecord.php(161): CComponent->__set("attributes", array("nome" => "", "nome_marca" => "And"))

#9	

+  C:\xampp\htdocs\sites\Macerata2\protected\controllers\AttivitaController.php(110): CActiveRecord->__set("attributes", array("nome" => "", "nome_marca" => "And"))

#10	

+  C:\xampp\htdocs\sites\yii\framework\web\actions\CInlineAction.php(49): AttivitaController->actionIndex()

#11	

+  C:\xampp\htdocs\sites\yii\framework\web\CController.php(308): CInlineAction->runWithParams(array("Attivita" => array("nome" => "", "nome_marca" => "And"), "yt0" => "Search"))

#12	

+  C:\xampp\htdocs\sites\yii\framework\web\filters\CFilterChain.php(133): CController->runAction(CInlineAction)

#13	

+  C:\xampp\htdocs\sites\yii\framework\web\filters\CFilter.php(40): CFilterChain->run()

#14	

+  C:\xampp\htdocs\sites\yii\framework\web\CController.php(1145): CFilter->filter(CFilterChain)

#15	

+  C:\xampp\htdocs\sites\yii\framework\web\filters\CInlineFilter.php(58): CController->filterAccessControl(CFilterChain)

#16	

+  C:\xampp\htdocs\sites\yii\framework\web\filters\CFilterChain.php(130): CInlineFilter->filter(CFilterChain)

#17	

+  C:\xampp\htdocs\sites\yii\framework\web\CController.php(291): CFilterChain->run()

#18	

+  C:\xampp\htdocs\sites\yii\framework\web\CController.php(265): CController->runActionWithFilters(CInlineAction, array("accessControl", "postOnly + delete"))

#19	

+  C:\xampp\htdocs\sites\yii\framework\web\CWebApplication.php(282): CController->run("index")

#20	

+  C:\xampp\htdocs\sites\yii\framework\web\CWebApplication.php(141): CWebApplication->runController("attivita/index")

#21	

+  C:\xampp\htdocs\sites\yii\framework\base\CApplication.php(180): CWebApplication->processRequest()

#22	

–  C:\xampp\htdocs\sites\Macerata2\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();

anche questa:




                        array('descrizione, indirizzo, image','nome_marca','safe'),




così




                        array('descrizione, indirizzo, image, nome_marca','safe'),




un pò di impegno…suvvia :rolleyes:

Concordo con st4anny, prima di postare di nuovo lo stesso errore, prova a fare il debug in questa maniera:

  • cancella (o commenta per gli utenti piu’ scafati) tutte le rules

  • quando non hai piu’ errori, aggiungile una alla volta, e se hai un errore, correggilo.

mi scuso, stavolta ho fatto un debug più accurato prima di postare :P, c’erano altri errori sulla rules del modello marche; ora di errori non ne ho più però la query non ottiene risultati!

la search nel model attivita: dove nome marca che è il parametro, l’ho impostato anche come nome del campo della tabella marche nel database




public function search()

	{


 $criteria=new CDbCriteria;

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

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

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


    	if ($this->nome_marca){

                   $criteria->with= array('marches');

                   $criteria->together= true;

                   $criteria->compare('marches.nome_marca', $this->nome_marca,true);

               }

    return new CActiveDataProvider($this, array(

        'criteria'=>$criteria,

    ));

	}



poi le tre tabelle, attivita(id,nome,coordinate,descrizione),marche(id,nome_marca,descrizione), marche_attivita(dove ho le foreign key, con i campi: marche_id, attivita_id)

esempio: tabella attivita(id=9,nome=attivita1); marche(id=1,nome_marca= marca1),tabella marche_attivita(attivita_id = 9, marche_id= 1)

però non ottengo risultati…,dovrebbe comparire il nome dell’attività 1

usando addCondition mi funziona!, presumo che la costruzione precedente sia sbagliata

postaci come hai risolto allora ;)

Ho utilizzato il secondo metodo che mi è stato consigliato, però essendo in fase di studio volevo capire entrambi e quale fosse il più performante.




$criteria=new CDbCriteria;

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

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

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

    


              

		if ($this->nome_marca){

     				$criteria->addCondition('id in (SELECT attivita_id FROM attivita_marche WHERE marche_id IN (SELECT id FROM marche WHERE nome like :nome_marca))');

                    $criteria->params[':nome_marca']='%'.$this->nome_marca.'%';

}



Penso che siano equivalienti, la differenza e’ che la prima compare con = e la seconda con like (e comunque comparano il nome e non l’id).

Dal punto di vista della performance credo che la prima sia meglio, perche’ dicono che le join siano meglio delle IN, specialmente quando le IN sono grandi