Buena noche, he trabajado un poco con consultas relacionales entre dos
tablas, por medio de las relaciones creadas en el modelo que Yii genera
automáticamente, más en este momento requiero hacerlo con tres tablas
las cuales son las siguientes (los puntos suspensivos representan campos
de poca relevancia):
-Lineas (id_linea, linea...........)
-Referencias (id_referencia, id_linea, referencia, imagen (este campo guarda una ruta de la imagen).............)
-Inventario (id_inventario, id_referencia, cantidad, fecha, estado, ..............)
Los siguientes son los métodos "relations" y "search" del modelo de la tabla "inventario" (cuyo CRUD completo lo genere por gii)
Código PHP:
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(
'creadoPor' => array(self::BELONGS_TO, 'Usuarios', 'creado_por'),
'editadoPor' => array(self::BELONGS_TO, 'Usuarios', 'editado_por'),
'idReferencia' => array(self::BELONGS_TO, 'Referencias', 'id_referencia'),
'referencia' =>array(self::BELONGS_TO, 'Referencia', 'id_referencia'),
'creador' =>array(self::BELONGS_TO, 'Usuario', 'creado_por'),
'editor' =>array(self::BELONGS_TO, 'Usuario', 'editado_por'),
);
}
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->condition = "estado='Ingreso'";
$criteria->compare('id_inventario',$this->id_inventario);
$criteria->compare('id_referencia',$this->id_referencia);
$criteria->compare('cantidad',$this->cantidad);
$criteria->compare('estado',$this->estado,true);
$criteria->compare('fecha',$this->fecha,true);
$criteria->compare('creado_por',$this->creado_por);
$criteria->compare('creado_en',$this->creado_en,true);
$criteria->compare('editado_por',$this->editado_por);
$criteria->compare('editado_en',$this->editado_en,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
La acción "admin" (del controlador) para usar el buscador, está intacta (no lo he modificado).
Código PHP:
public function actionAdmin()
{
$model=new Inventario('search');
$model->unsetAttributes(); // clear any default values
$lineas = $model->obtenerLineas();
$usuarios = $model->obtenerUsuarios();
if(isset($_GET['Inventario']))
$model->attributes=$_GET['Inventario'];
$this->render('admin',array(
'model'=>$model, 'lineas'=>$lineas, 'referencias'=>$referencias, 'usuarios'=>$usuarios,
));
}
Y
la vista contiene dos listas desplegables la segunda es dependiente de
la primera y funciona sin problema, la hice basado en este link
http://www.yiiframework.com/wiki/24/...dent-dropdown/,
Código PHP:
<div class="wide form">
<?php $form=$this->beginWidget('CActiveForm', array(
'action'=>Yii::app()->createUrl($this->route),
'method'=>'get',
)); ?>
<div class="row">
<?php echo CHtml::label('Línea', 'Línea'); ?>
<?php
echo CHtml::dropDownList('id_linea','', CHtml::listData(Linea::model()->findAll($lineas),'id_linea','linea'),
array('empty'=>'',
'ajax' => array(
'type'=>'POST', //request type
'url'=>CController::createUrl('inventario/obtenerReferencias'),
'update'=>'#Inventario_id_referencia', //selector to update
)
)
);
?>
</div>
<div class="row">
<?php echo $form->label($model,'id_referencia'); ?>
<?php echo CHtml::dropDownList('Inventario[id_referencia]','Inventario_id_referencia', array(),array('empty'=>'')); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Buscar'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- search-form -->
solo
deje dos campos en el formulario de búsqueda, pues solo me pidieron
esos, una vez seleccionó una línea, me despliega (por medio de la
petición ajax) en la otra lista las referencias relacionadas a esta
línea y una vez seleccionó una referencia, puedo consultar sin problema
los inventarios relacionados a la referencia, más requiero que si se
selecciona una línea, pero no una referencia, se puedan consultar todos
los inventarios relacionados a las líneas "hijas" de la referencia.
Por si les es útil (más no creo que necesario mencionar en relación a mi
necesidad) les dejo la acción que se ejecuta en la petición ajax:
Código PHP:
public function actionObtenerReferencias()
{
$data=Referencia::model()->findAll('id_linea=:id_linea',
array(':id_linea'=>(int) $_POST['id_linea']));
$data=CHtml::listData($data,'id_referencia','referencia');
echo CHtml::tag('option',
array('value'=>''),CHtml::encode(''),true);
foreach($data as $value=>$name)
{
echo CHtml::tag('option',
array('value'=>$value),CHtml::encode($name),true);
}
}
y la función del modelo con la cual consultó las referencias que se cargan por defecto en la primera lista desplegable:
Código PHP:
public function obtenerReferencias()
{
$criteria = new CDbCriteria;
$criteria->select = "id_referencia, referencia";
$criteria->order = "referencia";
return $criteria;
}
Supongo
que hay que modificar el método "search" del modelo, más no tengo claro
cómo hacerlo, he leído sobre las consultas con criteria, más aún me
parecen un poco confusas, si alguno de uds me puede ayudar con esto, se
lo agradecería mucho.
De igual manera les agradecería si alguno sabe cómo imprimir de forma
"100% limpia" (no un array, ni nada ambiguo, como ya he visto en muchos
posts) las consultas ejecutadas, por criteria.
Gracias por su atención.