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)
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).
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/creating-a-dependent-dropdown/,
<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:
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:
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.