Yii Framework Forum: zapisywanie danych do dwóch modeli - Yii Framework Forum

Jump to content

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

zapisywanie danych do dwóch modeli Rate Topic: -----

#1 User is offline   Deimos 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 18
  • Joined: 27-July 10

Posted 31 July 2010 - 10:45 AM

Mam następujący problem. Chciałem sporzadzić formularz do edytowania uprawnien dla danej grupy użytkowników. Struktura tabel w/g AuthManager. Zrobiłem formularz w którym można zmienić nazwe grupy, opis, oraz zaznaczyć (lub odznaczyć) uprawnienia:
formularz:
<?php $form=$this->beginWidget('CActiveForm', array(
	'id'=>'grupy-form',
	'enableAjaxValidation'=>true,
)); ?>

	<p class="note">Pola oznaczone <span class="required">*</span> są wymagane.</p>

	<?php echo $form->errorSummary($model); ?>

	<div class="row">
		<?php echo $form->labelEx($model,'nowaNazwa'); ?>
		<?php echo $form->textField($model,'nowaNazwa',array('size'=>60,'maxlength'=>128)); ?>  
		<?php echo $form->error($model,'nowaNazwa'); ?>
	</div>
    <div class="row">
		<?php echo $form->labelEx($model,'nowyOpis'); ?>
		<?php echo $form->textField($model,'nowyOpis',array('size'=>60)); ?>  
		<?php echo $form->error($model,'nowyOpis'); ?>
	</div>
	
	<div class="row">
	
	<?php 
	$this->widget('zii.widgets.grid.CGridView', array(
	'id'=>'uprawnienia-grupy-grid',
	'dataProvider'=>$dataProvider,
	'selectableRows'=>$dataProvider->getItemCount(),
	'columns'=>array(
				array(
			        'name'=>'id',
			        'value'=>'$this->grid->dataProvider->getPagination()->getOffset()+$row+1',
			        'header'=>'Nr.',
			        'filter'=>false,
				),
				'description',
				array(
                	'class'=>'myCheckBoxColumn',
					'name'=>'upraw',
					'value'=>'$data->name',
                	'checked'=>
						isset($_GET['name'])?'AuthItemChild::model()->exists("parent=:parent and child=:child", array(":parent"=>"'.$_GET['name'].'",":child"=>$data->name ))':'false',
						                 
                ),
   	)
	)); 
	?>
	
	
	</div>
	
	<div class="row buttons">
		<?php echo CHtml::submitButton('Zatwierdź'); ?>
	</div>

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

</div><!-- form -->


Do tego stworzyłem klase modelu CFormModel (UprawnieniaForm)

public $nazwa;
	public $opis;
	public $nowaNazwa;
	public $nowyOpis;
	public $uprawnienia=array();

.
.
.(reszta modelu)
.
.

public function save(){
		$auth = Yii::app()->authManager;
		$grupa = $auth->getAuthItem($this->nazwa);
		
		//edycja istniejącej grupy else tworzenie nowej
		if(isset($grupa)){
			//sprawdz czy istniejace w bazie powiazania sa zgodne z nowymi, jesli nie to usun
			$records = AuthItemChild::model()->findAllByAttributes(array('parent'=>$this->nazwa));
			if(!empty($records)){
				foreach($records as &$rec){
					$znalazl = false;
					foreach($this->uprawnienia as &$upr){
						if($rec->child==$upr){
							$znalazl = true;
							break;
						}
					}
					if(!$znalazl){
						$grupa->removeChild($rec->child);
					}
					unset($upr);
				}
				unset($rec);
			}
			//dodaj nowe uprawnienia, ale tylko te ktore nie sa juz zapisane
			foreach($this->uprawnienia as &$upr){
				if(!empty($records)){
					$znalazl = false;
					foreach($records as &$rec){
						if($upr==$rec->child){
							$znalazl = true;
							break;
						}
					}
					if(!$znalazl){
						$grupa->addChild($upr);
					}
					unset($rec);
				}
				else{
					$grupa->addChild($upr);	
				}
			}
			unset($upr);
			return true;
		}
		//tworzenie nowej grupy
		else{
			$grupa = $auth->createRole($this->nazwa, $this->opis);
			if(!empty($this->uprawnienia)){
				foreach($this->uprawnienia as &$upr){
					$grupa->addChild($upr);
				}
			}
			return true;
		}
		return false;


i w kontrolerze wywołuje taką akcje

public function actionEdytujGrupe(){
		if(AuthItem::model()->exists(array('name'=>$_GET['name']))){
			$model = new UprawnieniaForm;
			$model->nazwa = $_GET['name'];
			
			if(isset($_POST['UprawnieniaForm'])){
				$model->nowaNazwa = $_POST['UprawnieniaForm']['nowaNazwa'];
				$model->nowyOpis = $_POST['UprawnieniaForm']['nowyOpis'];
				if(isset($_POST['upraw'])){
					$model->uprawnienia = $_POST['upraw'];
				}
				else $model->uprawnienia = array();
				if($model->save()){
					$modelAI = AuthItem::model()->findByAttributes(array('name'=>$model->nazwa));
					$modelAI->setAttribute('name',$model->nowaNazwa);
					$modelAI->setAttribute('description',$model->nowyOpis);
					if($modelAI->update()){
						//echo $modelAI->description;
						$this->redirect(array('grupy'));
					}
				}
				
			}
			else{
				$modelAI = AuthItem::model()->findByAttributes(array('name'=>$_GET['name']));
				$model->nowaNazwa = $_GET['name'];
				$model->nowyOpis = $modelAI->description;
			}
			$dataProvider=new CActiveDataProvider(new AuthItem,
				array(
					'criteria'=>array(
						'condition'=>'type<2',
					),
				    'pagination'=>array(
					        'pageSize'=>40,
					 ),
				)
			);
			
			$this->render('edytujGrupe',array('model'=>$model,'dataProvider'=>$dataProvider, 'name'=>$model->nazwa));
		}
		else{
			throw new CHttpException(404,'Nie ma takiej grupy.');
		}
	}

Wszystko działa ładnie jak robię pojedynczo rzeczy, np. zmieniam uprawnienia, zmienia się, zmieniam opis, zmienia się, zmieniam nazwę, zmienia się.
Wysypuje się w sytuacji kiedy chce zmienić i nazwę i uprawnienia. W akcji wyraźnie najpierw wykonuje oeracje save na rekordzie jeszcze w starej nazwie, dopiero potem zmieniam nazwe rekoru, a wrezultacie dostaje taki błąd:

Quote

CDbCommand failed to execute the SQL statement: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'nowaNazwa' for key 1


I do tego powstaje nowy rekord w bazie o wprowadzonej nowej nazwie i bez uprawnien.
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