Yii Framework Forum: [Risolto] Vista Relazione Molti A Molti (View Many To Many) - Yii Framework Forum

Jump to content

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

[Risolto] Vista Relazione Molti A Molti (View Many To Many) Relazione molti a molti realizzare un view per insert delete etcc. Rate Topic: -----

#1 User is offline   roccodelux 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 27
  • Joined: 08-September 12

Posted 08 September 2012 - 05:25 AM

Ciao a tutti e prima di tutto vi ringrazio per il supporto che fornite alla comunità di yii in italiano.
Vengo al problema:
Ho una relazione molti a molti.
Sto cercando di realizzare un view ( insert, update, delete).
My link
Mi piacerebbe fare una vista gridview padre figlio come indicato nel seguente wiki:
View Padre Figlio

Putroppo ci sono solo spezzoni di codice e manca l'esempio completo e visto che sono nuovo di yii non sono riuscito a realizzare l'esempio del wiki.

Avete qualche esempio di codice pronto ?
Oppure come avete trattato le view di relazioni molti a molti ?

Ho girato quasi tutto il forum italiano ma non ho trovato nulla, e quindi una soluzione sarebbe utile a tutta la comunità di YII.

Grazie a tutti.

PS: Come esempio di tabelle DB potete prendere quello del wiki indicato sopra.
0

#2 User is offline   sensorario 

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

Posted 08 September 2012 - 05:43 AM

La tua domanda mi sembra un po' confusa. Tu vorresti fare un crud, per una relazione molti a molti. Una relazione di tipo padre/figlio non la vedo esattamente come molti a molti. Un figlio ha un solo padre. Potresti spiegare meglio qual'è il problema che stai cercando di risolvere?
0

#3 User is offline   roccodelux 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 27
  • Joined: 08-September 12

Posted 08 September 2012 - 06:45 AM

View Postsensorario, on 08 September 2012 - 05:43 AM, said:

La tua domanda mi sembra un po' confusa. Tu vorresti fare un crud, per una relazione molti a molti. Una relazione di tipo padre/figlio non la vedo esattamente come molti a molti. Un figlio ha un solo padre. Potresti spiegare meglio qual'è il problema che stai cercando di risolvere?


Cerco di spiegarmi con un esempio.
ho tre tbl Categoria, Prodotti, CategoriaProdotti ( vedi file allegato)

Un prodotto può appartenere a più categoria, come una categoria può appartenere a più prodotti.
Valori Categoria:
  • Surgelati
  • Fresco

+------+---------+
| id | categoria |
+----------------+
| 1 | Surgelati |
| 2 | Fresco |
+-----------------|


Valori Prodotti:
[*]Carne
[*]Pesce
[/list]

+------+---------+
| id | prodotti |
+----------------+
| 1 | carne |
| 2 | pesce |
+-----------------|

tbl_ categoria prodotti:

+------+---------+---------+
| id | id_prodot | id_categ |
+----------------+----------
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 1 |
-----------------------------

Per gestire la caegoria posso fare una vista semplice e un form per registrare le categorie ovvero un crud generato con gii.

Per gestire i prodotti non mi basta una view semplice con un form perchè devo poter inserire molteplici categoria. Quindi a me interessa come poter gestire la view Prodotti per fare le operazioni crud ( insert, update, delete)

Spero di essere stato chiaroAttached File  Schermata 09-2456179 alle 13.25.40.png (27.42K)
Number of downloads: 23
0

#4 User is offline   sensorario 

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

Posted 08 September 2012 - 06:53 AM

Chiaro sei stato chiaro. Io ti suggerire di usare un po' di ajax. In pratica fai un form che invia una post in background e come funziona di callback ricarica lo stesso form e l'elenco delle chiavi esterne.
0

#5 User is offline   roccodelux 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 27
  • Joined: 08-September 12

Posted 08 September 2012 - 08:47 AM

View Postsensorario, on 08 September 2012 - 06:53 AM, said:

Chiaro sei stato chiaro. Io ti suggerire di usare un po' di ajax. In pratica fai un form che invia una post in background e come funziona di callback ricarica lo stesso form e l'elenco delle chiavi esterne.


Hai un esempio di codice? Attached File  Schermata 09-2456179 alle 15.43.55.png (216.94K)
Number of downloads: 35
Mi piacerebbe realizzare una cosa del genere Attached File  Schermata 09-2456179 alle 15.43.55.png (216.94K)
Number of downloads: 35

Oppure dovrei usare un'estensione tipo http://www.yiiframew...nyajaxcrudadmin ma non mi piace molto.
0

#6 User is offline   sensorario 

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

Posted 08 September 2012 - 09:50 AM

Con esempio di codice intendevo PHP. Ma va bene lo stesso. Adesso mi serve di capire che cosa ti manca per arrivare ad implementare qualche cosa come in quell'immagine. Poi posso provare ad aiutarti. Se dovessi farlo io, come ti dicevo, andrei dritti verso una soluzione con ajax, e mi scriverei le view del form, dell'elenco dei contatti, qualche richiesta json per i dati già inseriti, molto jQuery per gestire la parte asincrona (con asincrona intendo ajax).
0

#7 User is offline   roccodelux 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 27
  • Joined: 08-September 12

Posted 10 September 2012 - 06:48 AM

Il mio problema era a monte, ovvero capire come si gestiscono le relazioni molti e molti con Yii. Penso di averle capite e vi posto un esempio completo che ho realizzato dopo un fine settimana di studio. ( sono alla prime armi con yii ;-) ).
Nulla di difficile e spero sia utile alla comunità.
In questo primo esempio spiegherò la lettura delle relazioni molti a molti. Nei prossimi giorni spero di fare qualche esercizio con le insert ed update e postare la soluzione.
Abbiamo tre tabelle: utenti,utenti_permessi,permessi
Attached File  er_test.JPG (30.63K)
Number of downloads: 13
I valori della tabella permessi possono essere: lettura,scrittura,modifica, etc

Un utente appartiene a più permessi come un permesso appartiene a più utenti.

--
-- Struttura della tabella `permessi`
--

CREATE TABLE IF NOT EXISTS `permessi` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nome` varchar(40) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;

--
-- Dump dei dati per la tabella `permessi`
--

INSERT INTO `permessi` (`id`, `nome`) VALUES
(1, 'insert'),
(2, 'read'),
(5, 'execute'),
(6, 'full');

--
-- Struttura della tabella `utenti`
--

CREATE TABLE IF NOT EXISTS `utenti` (
  `id` int(11) NOT NULL,
  `nome` varchar(45) DEFAULT NULL,
  `cognome` varchar(45) DEFAULT NULL,
  `id_amministratore` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dump dei dati per la tabella `utenti`
--

INSERT INTO `utenti` (`id`, `nome`, `cognome`, `id_amministratore`) VALUES
(1, 'paolo', 'rossi', 1),
(2, 'vincenzo', 'nuoti', 0),
(3, 'Pippo', 'Pippo', 1);

--
-- Struttura della tabella `utenti_permessi`
--

CREATE TABLE IF NOT EXISTS `utenti_permessi` (
  `utenti_id` int(11) NOT NULL,
  `permessi_id` int(11) NOT NULL,
  PRIMARY KEY (`utenti_id`,`permessi_id`),
  KEY `fk2` (`permessi_id`),
  KEY `fk1` (`utenti_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dump dei dati per la tabella `utenti_permessi`
--

INSERT INTO `utenti_permessi` (`utenti_id`, `permessi_id`) VALUES
(1, 1),
(1, 2),
(3, 5),
(3, 6);

--
-- Limiti per le tabelle scaricate
--

--
-- Limiti per la tabella `utenti_permessi`
--
ALTER TABLE `utenti_permessi`
  ADD CONSTRAINT `utenti_permessi_ibfk_3` FOREIGN KEY (`permessi_id`) REFERENCES `permessi` (`id`),
  ADD CONSTRAINT `utenti_permessi_ibfk_1` FOREIGN KEY (`utenti_id`) REFERENCES `utenti` (`id`);





Possiamo creare velocemente i model della classe Utenti e Permessi con gii.

Nel model Utenti ( se gii non l'ha generato) aggiungere:

public function relations()
	{
	
		return array(
				'permessis' => array(self::MANY_MANY, 'Permessi', 'utenti_permessi(utenti_id, permessi_id)'),
		);
	}




Nella Model Permessi aggiungere :
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(
			'utentis' => array(self::MANY_MANY, 'Utenti', 'utenti_permessi(permessi_id, utenti_id)'),
		);
	}



Velocemente vi mostro come scorrere i record di object.
Nella view SiteController inserite la seguente azione che mostra gli utenti appartenente ai permessi e viceversa:


public function actionTestManyToMany1()
	{
		// findAll restituisce un record di oggetti.
		$permessi = Permessi::model()->findAll();
		$utenti = Utenti::model()->findAll();
	
		foreach($permessi as $permesso)
		{
			echo $permesso->nome . " Questo permesso associato a  " . count($permesso->utentis) . " utenti. Essi sono:<br />";
			foreach($permesso->utentis as $utente)
			{
				echo $utente->nome . "<br />";
			}
			echo "<br />";
		}
	
		echo "<hr />";
	
		foreach($utenti as $utente)
		{
				
			echo $utente->nome . " sono associati n= " . count($utente->permessis) . " permessi. Essi sono :<br />";
			foreach($utente->permessis as $permesso)
			{
				echo $permesso->nome . "<br />";
			}
			echo "<br />";
		}
	}




Esempio di query:
Trova tutti i permessi associati ad un utente con id=1 e il cui amministratore_id=1

public function actionTestManyToMany()
	{
		// findAll restituisce un record di oggetti.
		$permessi = Permessi::model()->findAll();
		$criteria=new CDbCriteria;
		$criteria->select='*';
		$criteria->condition='id_amministratore=:_id AND id=:idp';
		$criteria->params=array(':_id'=>1,':idp'=>1);
		$utenti=Utenti::model()->findAll($criteria);
	
		foreach($permessi as $permesso)
		{
			echo $permesso->nome . " Questo permesso associato a  " . count($permesso->utentis) . " utenti. Essi sono:<br />";
			foreach($permesso->utentis as $utente)
			{
				echo $utente->nome . "<br />";
			}
			echo "<br />";
		}
	
		echo "<hr />";
	
		foreach($utenti as $utente)
		{
				
			echo $utente->nome . " sono associati n= " . count($utente->permessis) . " permessi. Essi sono :<br />";
			foreach($utente->permessis as $permesso)
			{
				echo $permesso->nome . "<br />";
			}
			echo "<br />";
		}
	}



Giorno 11-09-2012

Lavorare con i dataprovider - CActiveDataProvider
Negli esempi precedenti abbiamo lavorato con i CActiveRecord.

Lavorare con gli oggetti di tipo CActiveRecord è utile quando usiamo
nelle viste zii.widgets.CListView e zii.widgets.CDetailView.

Velocementi con gii generiamo il CRUD del model Utenti.

Nell'actionIndex di UtentiController abbiamo una istanza di CActiveRecord


public function actionIndex()
	{
		$dataProvider=new CActiveDataProvider('Utenti');
		$this->render('index',array(
			'dataProvider'=>$dataProvider,
		));
	}


il dataprovider viene passato alla vista index di Utenti.
Nella vista utenti index troviamo un zii.widgets.CListView a cui viene passato il dataprovider.
Come ItemView troviamo il _view.php
Noi per vedere tutti i permessi di un utente dobbiamo lavorare su quest'ultimo.
utenti/_viem.php

//visualizzaziamo tutti i permessi associati ad un utente
if (count($data->permessis) > 0): 
	?>
    <div align="left">
      <b>Pemessi:</b> 
      
      <?php
      // scorro tutti i permessi
      foreach ($data->permessis as $item) : ?>
      <ul>
        <li><?php echo $item->nome; ?></li>
       </ul>
      <?php endforeach; ?>
    </div>
  <?php endif; ?>





Vaediamo anche la relazione molti a molti nel componente zii.widgets.CDetailView
usato nella vista utenti/view


<?php $this->widget('zii.widgets.CDetailView', array(
	'data'=>$model,
	'attributes'=>array(
		'id',
		'nome',
		'cognome',
	    array('label'=>'Permessi',
				'type'=>'raw',
				   
				  'value'=>$model->RelatedPermessis, // la classe va inserita nel model Utenti
					
				),
        
			),
		
		)); ?>






Model/Utenti


	public function getRelatedPermessis()
	{
		$out=CHtml::listData($this->permessis,'id','nome');
		$puntolista = '<ul>';
		foreach($out as $key=>$value) {
			
			//$puntolista .= sprintf('<li>%s</li>', CHtml::link($value, array('artikel/view', 'id' => $key)));
			$puntolista .= sprintf('<li>%s</li>',$value);
	
		}
		$puntolista .= '</ul>';
		return $puntolista;
	}
	



Leggere - CheckBoxList Many to Many
Se volessimo visualizzare una lista di checkbox (checkboxlist) modificare la precendente classe
come di seguito:
Model/Utenti

public function getRelatedPermessisCheckBox()
	{
		$listachiave=array();
		$lista=CHtml::listData($this->permessis,'id','nome');
		foreach($lista as $key=>$value){
			$listachiave[]=$key;
		}
		$out=CHtml::checkBoxList("ListaPermessi",$listachiave, CHtml::listData(Permessi::model()->findAll(), 'id', 'nome'),array('disabled'=>true));
		return $out;
	}



INSERT ED UPDATE


Per la insert ed update ci avvaliamo di un componente che ci facilita di molto la vita.
Si chiama CSaveRelationBehavior.php Download

Scaricate il componente e inseritelo nella cartella components.
Inserite in config/main.php
// autoloading model and component classes
	'import'=>array(
		'application.models.*',
		'application.components.*',
		'application.extensions.CAdvancedArBehavior'
	),

 


Nel model Utenti.php inserire le relazioni e il behaviors:

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(
				'permessis' => array(self::MANY_MANY, 'Permessi', 'utenti_permessi(utenti_id, permessi_id)'),
				//'services' => array(self::MANY_MANY, 'Service', 'LibraryService(libraryID, serviceID)'),
				'utentipermessis'=>array(self::HAS_MANY, 'utenti_permessi', 'utenti_id'),
		);
	}
	
	public function behaviors(){
		return array(
				'CSaveRelationsBehavior' => array(
						'class' => 'CSaveRelationsBehavior',
						'relations' => array(
								'utentipermessis'=>array("message"=>"Please, check the permessi"),
								//'libraryComments'=>array("message"=>"Please, check the comments"),
								//'services'=>array("message"=>"Please, check the services")
						)
				)
		);
	}





Per l'insert nella view _form inserire:

	<?php 
	
	$selected_permission = array(); 
	foreach($model->permessis as $permessi) array_push($selected_permission, $permessi->id);
	//print_r($selected_services);
	?>
	
   
	<div class="row">
        <?php echo $form->labelEx($model, 'permessi'); ?>
        <?php // echo $form->checkBoxList($model, 'permessis', CHtml::listData(Permessi::model()->findAll(), 'id', 'nome'), array('labelOptions' => array('style' => 'display:inline'))); ?>
       <?php echo CHtml::checkBoxList('Permessi', $selected_permission , CHtml::listData(Permessi::model()->findAll(), 'id', 'nome'),array('template'=>'{input} {label}','labelOptions'=>array('style'=>'display:inline;'))); ?>
        <?php echo $form->error($model, 'colors'); ?>
	</div>



Nel conttroller Utenti l'actione Create diventa:

	public function actionCreate()
	{
		$model=new Utenti;

		// Uncomment the following line if AJAX validation is needed
		// $this->performAjaxValidation($model);

		if(isset($_POST['Utenti']))
		{
			
		//var_dump($_POST['Utenti']['permessis']);
			//exit;
			
			$model->attributes=$_POST['Utenti'];
			$model->setRelationRecords('permessis',is_array(@$_POST['Permessi']) ? $_POST['Permessi']: array());
			
			if($model->save())
				$this->redirect(array('view','id'=>$model->id));
		}

		$this->render('create',array(
			'model'=>$model,
		));
	}





ACTION UPDATE
Per l'update
sempre nel controller Utente

public function actionUpdate($id)
	{
		$model=$this->loadModel($id);

		// Uncomment the following line if AJAX validation is needed
		// $this->performAjaxValidation($model);

		if(isset($_POST['Utenti']))
		{
			$model->attributes=$_POST['Utenti'];
			$model->setRelationRecords('permessis',is_array(@$_POST['Permessi']) ? $_POST['Permessi']: array());
			if($model->save())
				$this->redirect(array('view','id'=>$model->id));
		}

		$this->render('update',array(
			'model'=>$model,
		));
	}






dove loadModel

	public function loadModel($id)
	{
		$model=Utenti::model()->findByPk($id);
		if($model===null)
			throw new CHttpException(404,'The requested page does not exist.');
		return $model;
		
	}






Spero che questo tutorial vi sia stato utile.
Ciao A tutti
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