Dubbi Relazione Many_Many

Ciao a tutti! Sono nuovo del Forum e colgo l’occasione per ringraziarvi, dato che negli ultimi giorni i vostri post mi stanno salvando la vita :)

Sono almeno due giorni che sto impazzendo dietro a questa cosa; la soluzione che più si avvicina l’ho trovata qui

http://www.yiiframework.com/forum/index.php/topic/20284-salvare-relazioni-many-many/

ma non sono del tutto sicuro.

Vi spiego la situazione. Ho tre tabelle, per semplicità mi invento i nomi delle tabelle come seguono

USER

id

name

SPORT

id

name

description

etc…

USER_SPORTS

id

user_id

sport_it

Nel momento in cui vado a creare un nuovo user, voglio salvare quali sono gli sport praticati.

Con i post seguiti fino ad ora, ho eseguito i seguenti passaggi.

Nella view _form dell’User, visualizzo un CheckBoxList con l’elenco di tutti gli sport


echo CHtml::activeCheckBoxList(sports[]',null,Chtml::listData(Sports::model()->findAll(),'id','name'));

Mentra nel model dell’user, ho dichiarato la relation


'userSports'=> array(self::MANY_MANY, 'Sports', 'user_sports(user_id, sport_id)')

1)Per prima cosa, come posso verificare che venga selezionato almeno 1 checkbox dall’elenco? Immagino che debba inserire nei rules dell’User qualche cosa, ma cosa?

2)Una volta che effettuo questa validazione, come salvo i checkbox selezionati nella tabella user_sports?(devo utilizzare la funzione afterSave di User?)

3)Poi il problema più grande sorgerebbe quando devo andare a fare l’update dell’user. Come recuperare la lista dei checkbox, però con preselezionati gli sport già presenti della tabella user_sports? Se poi i checkbox selezionati vengono modificati, o tolti, come andare a modificare la lista dentro user_sports?

Vi ringrazio in anticipo per qualsiasi consiglio. Ciao,

Giacomo

Intanto benvenuto nel forum.

Per la validazione devi farla con una custom rules, una funzione che controlla se ce n’e’ almeno uno.

Aggiungi una proprieta’ sportsID al model e mettici la rule (in modo che sia safe).

Per caricare/salvare, fai cosi’:

salva nella afterSave (in create ti serve l’id):


		if (!is_null($this->sportsID)) {

			

			Yii::app()->db->createCommand()->delete('USER_SPORTS', 'user_id = :id', array(':id' => $this->id));

			

			if ($this->sportsID) {

				foreach ($this->sportsID as $sportId) {

					Yii::app()->db->createCommand()->insert('USER_SPORTS', array('user_id' => $this->id, 'sport_id' => $sportId));

				}

			}

		}

Nella after find carica con:


$this->sportsID = array_keys(CHtml::listData($model->sports, 'id', 'name'));

Grazie per la tempestiva risposta! :D

Con “Aggiungi una proprieta’ sportsID” intendevi creare una variabile con quel nome giusto? Ho seguito i tuo suggerimenti e funziona! Però non mi è molto chiaro

  1. come definire una custom rules

  2. a cosa serve la funzione afterFind.

ps: ma questi, a cosa servono? non centrano nulla con il mio caso?

eadvancedarbehavior

cadvancedarbehavior

advancedrelationsbehavior

Grazie mille!

Io ti consiglierei di usare codice tuo, e non di usare estensioni.

Le estensioni aggiungono codice (spesso poco commentato) al gia’ spesso framework.

Per rispondere alle tue domande:

La afterFind viene chiamata appena il record viene creato, e serve a caricare le scelte dal database (serve solo in update).

In alternativa puoi caricare nella actionUpdate dopo che carichi il model.

Una custom rules si definisce come una rule in rules:


public function rules()

{

  return array(

    array('sportsID', 'ha_scelto_uno_sport'),

  );

}

e una funzione con lo stesso nome:


public function ha_scelto_uno_sport()

{

  if (!$this->sportsID)

     $this->addError('sportsID', 'Ti deve per foggia piacere un qualche sport!')

}

Per le relazioni Many_Many forse ti potrebbe essere utile il seguente post: Many_Many

Ciao, non so come mai ma questa


$this->addError('sportsID', 'Ti deve per foggia piacere un qualche sport!')

non mi funziona. Ho risolto il problema aggiungendo la rules a parte


array('sportsID', 'required', 'message'=>'Ti deve per foggia piacere un qualche sport!'),

La create è fatta! ora proseguo con l’update e vediamo come va. Credo che mi farò risentire a breve :D

Grazie mille, ciao ciao

Grazie per la dritta, credo che però seguiro il consiglio di zaccaria a non utilizzare estensioni.

Grazie comunque!

Per l’update devi solo caricare dal db come ti ho gia’ scritto.