GUARDAR DATOS MULTIPLES CHECKBOXLIST - EN BASE DE DATOS

Hola a todos los programadores, he creado un proyecto con Gii para generar los modelos y los controladores.

ADJUNTO EL PROYECTO AQUI: 6773

project-gii.zip

DESEO DESDE EL FORMULARIO DE USUARIO PODER GUARDAR EN LA TABLA RELACION USUARIOS_IDIOMAS los idiomas pertenecientes a un usuario, muchisimas gracias… mas adelante expongo el codigo y las imagenes:

Mi base de datos es la siguiente:


USUARIOS |


id->PK |

nombre |

apellido |

documento |

direccion |

#id_genero->FK |

#id_profesion->FK |



GENEROS |


id->PK |

nombre |



PROFESIONES |


id->PK |

nombre |



IDIOMAS |


id->PK |

nombre |



USUARIOS_IDIOMAS |


#id_usuarios->FK |

#id_idiomas->FK |


6772

llenar_tabla_relacion.png

mi idea es que al momento de llenar el formulario para usuario, contenga los checkbox de idiomas, para saber qué idiomas maneja el usuario. Y por medio de esos checkbox guardar los registros en la tabla USER_LANGUAGE

pero realmente no se como hacer para que esto suceda.

Alguien me puede colaborar?

Model —> Usuario.php




<?php


/**

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

 *

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

 * @property integer $id

 * @property string $nombre

 * @property string $apellido

 * @property string $documento

 * @property string $direccion

 * @property integer $idGenero

 * @property integer $idProfesion

 */

class Usuario extends CActiveRecord

{

	/**

	 * Returns the static model of the specified AR class.

	 * @return Usuario the static model class

	 */

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}


	/**

	 * @return string the associated database table name

	 */

	public function tableName()

	{

		return 'usuarios';

	}


	/**

	 * @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('nombre, apellido, documento, direccion, idGenero, idProfesion', 'required'),

			array('idGenero, idProfesion', 'numerical', 'integerOnly'=>true),

			array('nombre, apellido, direccion', 'length', 'max'=>250),

			array('documento', 'length', 'max'=>20),

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

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

			array('id, nombre, apellido, documento, direccion, idGenero, idProfesion', '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(


			'genero'=>array(self::BELONGS_TO,'Genero','idGenero'),

			'profesion'=>array(self::BELONGS_TO,'Profesion','idProfesion'),

			'idiomas'=>array(self::MANY_MANY,'Idioma', 'usuarios_idiomas(id_usuarios,id_idiomas)'),


		);

	}


	/**

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

	 */

	public function attributeLabels()

	{

		return array(

			'id' => 'ID',

			'nombre' => 'Nombre',

			'apellido' => 'Apellido',

			'documento' => 'Documento',

			'direccion' => 'Direccion',

			'idGenero' => 'Id Genero',

			'idProfesion' => 'Id Profesion',

		);

	}


	/**

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

	 * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.

	 */

	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('nombre',$this->nombre,true);

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

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

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

		$criteria->compare('idGenero',$this->nombre);

		$criteria->compare('idProfesion',$this->nombre);


		return new CActiveDataProvider(get_class($this), array(

			'criteria'=>$criteria,

		));

	}

}




controller -> UsuarioController.php




<?php


class UsuarioController extends Controller

{

	/**

	 * @var string the default layout for the views. Defaults to '//layouts/column2', meaning

	 * using two-column layout. See 'protected/views/layouts/column2.php'.

	 */

	public $layout='//layouts/column2';


	/**

	 * @return array action filters

	 */

	public function filters()

	{

		return array(

			'accessControl', // perform access control for CRUD operations

		);

	}


	/**

	 * Specifies the access control rules.

	 * This method is used by the 'accessControl' filter.

	 * @return array access control rules

	 */

	public function accessRules()

	{

		return array(

			array('allow',  // allow all users to perform 'index' and 'view' actions

				'actions'=>array('index','view'),

				'users'=>array('*'),

			),

			array('allow', // allow authenticated user to perform 'create' and 'update' actions

				'actions'=>array('create','update'),

				'users'=>array('@'),

			),

			array('allow', // allow admin user to perform 'admin' and 'delete' actions

				'actions'=>array('admin','delete'),

				'users'=>array('admin'),

			),

			array('deny',  // deny all users

				'users'=>array('*'),

			),

		);

	}


	/**

	 * Displays a particular model.

	 * @param integer $id the ID of the model to be displayed

	 */

	public function actionView($id)

	{

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

			'model'=>$this->loadModel($id),

		));

	}


	/**

	 * Creates a new model.

	 * If creation is successful, the browser will be redirected to the 'view' page.

	 */

	public function actionCreate()

	{

		$model=new Usuario;


		// Uncomment the following line if AJAX validation is needed

		// $this->performAjaxValidation($model);


		if(isset($_POST['Usuario']))

		{

			$model->attributes=$_POST['Usuario'];

			if($model->save())

				$this->redirect(array('view','id'=>$model->id));

		}


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

			'model'=>$model,

		));

	}


	/**

	 * Updates a particular model.

	 * If update is successful, the browser will be redirected to the 'view' page.

	 * @param integer $id the ID of the model to be updated

	 */

	public function actionUpdate($id)

	{

		$model=$this->loadModel($id);


		// Uncomment the following line if AJAX validation is needed

		// $this->performAjaxValidation($model);


		if(isset($_POST['Usuario']))

		{

			$model->attributes=$_POST['Usuario'];

			if($model->save())

				$this->redirect(array('view','id'=>$model->id));

		}


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

			'model'=>$model,

		));

	}


	/**

	 * Deletes a particular model.

	 * If deletion is successful, the browser will be redirected to the 'admin' page.

	 * @param integer $id the ID of the model to be deleted

	 */

	public function actionDelete($id)

	{

		if(Yii::app()->request->isPostRequest)

		{

			// we only allow deletion via POST request

			$this->loadModel($id)->delete();


			// if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser

			if(!isset($_GET['ajax']))

				$this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));

		}

		else

			throw new CHttpException(400,'Invalid request. Please do not repeat this request again.');

	}


	/**

	 * Lists all models.

	 */

	public function actionIndex()

	{

		$dataProvider=new CActiveDataProvider('Usuario');

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

			'dataProvider'=>$dataProvider,

		));

	}


	/**

	 * Manages all models.

	 */

	public function actionAdmin()

	{

		$model=new Usuario('search');

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

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

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


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

			'model'=>$model,

		));

	}


	/**

	 * Returns the data model based on the primary key given in the GET variable.

	 * If the data model is not found, an HTTP exception will be raised.

	 * @param integer the ID of the model to be loaded

	 */

	public function loadModel($id)

	{

		$model=Usuario::model()->findByPk((int)$id);

		if($model===null)

			throw new CHttpException(404,'The requested page does not exist.');

		return $model;

	}


	/**

	 * Performs the AJAX validation.

	 * @param CModel the model to be validated

	 */

	protected function performAjaxValidation($model)

	{

		if(isset($_POST['ajax']) && $_POST['ajax']==='usuario-form')

		{

			echo CActiveForm::validate($model);

			Yii::app()->end();

		}

	}

}






USUARIO FORM —> form_.php




<div class="form">


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

	'id'=>'usuario-form',

	'enableAjaxValidation'=>false,

));




 ?>


	<p class="note">Fields with <span class="required">*</span> are required.</p>


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


	<div class="row">

		<?php echo $form->labelEx($model,'nombre'); ?>

		<?php echo $form->textField($model,'nombre',array('size'=>60,'maxlength'=>250)); ?>

		<?php echo $form->error($model,'nombre'); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model,'apellido'); ?>

		<?php echo $form->textField($model,'apellido',array('size'=>60,'maxlength'=>250)); ?>

		<?php echo $form->error($model,'apellido'); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model,'documento'); ?>

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

		<?php echo $form->error($model,'documento'); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model,'direccion'); ?>

		<?php echo $form->textField($model,'direccion',array('size'=>60,'maxlength'=>250)); ?>

		<?php echo $form->error($model,'direccion'); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model,'Genero'); ?>

		<?php echo $form->radioButtonList($model,'idGenero', CHtml::listData(Genero::model()->findAll(),'id','nombre'), array('separator'=>' ','labelOptions'=>array('style'=>'display:inline'))); ?>

		<?php echo $form->error($model,'idGenero'); ?>

	</div>


	

	<div class="row">

		<?php echo $form->labelEx($model,'Idioma'); ?>

		<?php echo $form->checkBoxList($model,'id', CHtml::listData(Idioma::model()->findAll(),'id','nombre'), array('separator'=>' ','labelOptions'=>array('style'=>'display:inline'))); ?>

		<?php echo $form->error($model,'idIdioma'); ?>

	</div>

	


	<div class="row">

		<?php echo $form->labelEx($model,'Profesion'); ?>

		<?php echo $form->dropDownList($model,'idProfesion',CHtml::listData(Profesion::model()->findAll(),'id','nombre'),array('empty'=>'seleccione una profesión')); ?>

		<?php echo $form->error($model,'idProfesion'); ?>

	</div>


	<div class="row buttons">

		<?php echo CHtml::submitButton($model->isNewRecord ? 'Guardar' : 'Save'); ?>

	</div>


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


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



6771

formulario_usuario.png

realmente no me guarda la seleccion del checkbox en la tabla relacion entre usuarios e idiomas… la webapp no genera ningun error pero no cumple con el requerimiento.

espero su pronta respuesta. muchas gracias

Buenas.

Revisa esto: http://www.eha.ee/labs/yiiplay/index.php/en/site/extension?view=tabular

Imaginemos que estás creando un usuario.

Cubres los datos del mismo, incluyendo los idiomas y haces click en el botón guardar.

Entonces se va a lanzar la función create, que crea un modelo de USUARIO, lo llena y lo guarda.

Los idiomas de ese usuario no están en el modelo de USUARIO, y por lo tanto, no te los va a guardar.

Lo que tienes que hacer es crear el modelo de la tabla de relación USUARIOS_IDIOMAS, recorrer el array $_POST con los datos de los idiomas seleccionados (y guardar los idiomas relacionados con el usuario).

Algo parecido a esto:




public function actionCreate()

        {

                $model=new Usuario;


                // Uncomment the following line if AJAX validation is needed

                // $this->performAjaxValidation($model);


                if(isset($_POST['Usuario']))

                {

                        $model->attributes=$_POST['Usuario'];

                        if($model->save())

                        {

                            foreach($_POST['nombreDelCheckboxListIdiomas'] as $row)// O donde tengas guardados los datos del checkboxlist.

                            {

                                // aquí vas guardando cada idioma mediante un modelo USUARIOS_IDIOMAS.

                                // q puedes crear aquí o fuera del bucle, tu decides.

                            }

                            $this->redirect(array('view','id'=>$model->id));

                        }

                }




Además, en tu vista tienes esto:




<div class="row">

                <?php echo $form->labelEx($model,'Idioma'); ?>

                <?php echo $form->checkBoxList($model,'id', CHtml::listData(Idioma::model()->findAll(),'id','nombre'), array('separator'=>' ','labelOptions'=>array('style'=>'display:inline'))); ?>

                <?php echo $form->error($model,'idIdioma'); ?>

        </div>



Lo cuál no es correcto, ya que le estás diciendo que el valor del idioma lo coga del id de $model, que sería el id del usuairo, ya que $model es el modelo de usuario.

Un saludo.

hola, me podrias ayudar por favor con mi tema?el dropdownlist no se como traer datos de una tabla para que los muestre en un dropdownlist, y una duda mas la variable $model es reservada de yii o solo la usan de ejemplo?

Buenas.

1- La variable $model es una variable. No puede estar (o no debería estar) reservada en Yii ya que es una "varaible". Tu puedes llamarle si quieres $datosModelo o como quieras. Simplemente es una variable en dónde vas a recoger los datos de un modelo.

2- Para llenar unha lista desplegable puedes hacerlo así :




echo $form->dropDownList($model, 'yourAttributeName', 

                        CHtml::listData(

                                    SomeModel::model()->findAll(

                                                        array(

                                                            'order' => 'SomeField ASC',

                                                        )), 

                                    'SomeFieldAsKey', 'SomeFieldAsText'),

                        array(

                            'prompt' => 'MessageIfNothingSelected'

                            )); 



Un saludo.

Muchas gracias, ahora tengo una duda mas, cuando quiero realizar un metodo en el controlador para usar una consulta sql inner join, como debo hacer?yo hice un tema, pero el codigo esta mal funcionaba con una sola tabla, pero cuando agrego dos tablas y utilizo inner join no funciona.

Hola matthewjara90, estuve viendo el post, escucha hermano con el ORM cumpliendo su rol simplemente si quieres dentro del action refereciar otra tabla asignas el modelo en cuestión a otra variable que no sea $model sino una definida por ti y listo… la captura que haces de la variable global la manejas de la forma que te parezca más conveniente… Buscas, agregas… modificas, en fin lo que necesites…

Suerte y éxitos…

Buenas de nuevo.

No entiendo que es lo que quieres hacer.

Yii es un framework MVC, con lo que la mayor parte de las operaciones sobre base de datos están implementadas en los modelos.

Pq quieres hacer un INNER JOIN?

Por ejemplo, imagínate que tenemos 2 tablas:

TABLA 1

clave1

nombre1

TABLA2

clave2

clave1

nombre2

Vas a tener 2 modelos llamados TABLA1 y TABLA2.

En el modelo TABLA2, tendrás 1 relación (imaginemos q se llama FK_T1) definida en la función [b]relations/b.

Entonces, imagínate que quieres recoger nombre1 de la TABLA1 dentro del controlador de TABLA2:




$model2 = $this->loadModel($clave2);// Clave 2 será el identificador del registro de la tabla 2 que quieras cargar.


$nombre1 = $model2->FK_T1->nombre1;// Aquí recoges el nombre 1 relacionado con el registro cargado de la tabla 2.

                                   //Y fíjate que no has tenido que volver a hacer otra consulta.



Espero que sea esto lo que buscas.

Si no es esto, siempre puedes hacer lo siguiente en un controlador:




$model = TABLA2::find('CLAVE2 = 234');


// o bien


$datos = Yii::app()->db->createCommand('SELECT A.* FROM TABLA1 A INNER JOIN TABLA2 B WHERE A.CLAVE1=B.CLAVE2')->queryAll();



Un saludo.

Hola hermano: mira, las ventajas que te ofrece el framework hacen que el empleo directo de instrucciones SQL a menos que estén perfectamente justificadas se constituye en una mala práctica. Esto es mucho más extenso pero no me gustan los Posts tediosos sino ser objetivo. Creo entender que lo que buscas es esto:

Este es un sistema para el control de las actividades de postgrado de una universidad en este código verifico si el usuario tiene el cargo de decano y en caso positivo

condiciono el criterio que paso al findAll para que solo se listen en el reporte las actividades convocadas por ese decano… Espero te sirva hermano y éxitos en tu sistema. No pierdas la comunicación y dime si te sirvió…

		if(yii::app()-&gt;user-&gt;checkAccess('decano'))


		{


			&#036;access_id = yii::app()-&gt;user-&gt;id;


			


			&#036;criteria=new CDbCriteria();


			&#036;criteria-&gt;with = array(


			    'Actividad' =&gt; array(


		    	    'joinType'=&gt;'INNER JOIN',


			    	   'with' =&gt; array(


		    	    	  'convoca' =&gt; array('joinType' =&gt; 'INNER JOIN') // esto puede extender a otros inner join y seguir enlazando


			        )


			    ),            


			); 


			&#036;criteria-&gt;addCondition(&quot;convoca.CodDecano = '&quot;.&#036;access_id.&quot;'&quot;);


			&#036;model = Reporte::model()-&gt;findAll(&#036;criteria);


		}