relaciones

Hola, necesito su ayuda

Tengo un catalogo de lideres (usuarios), un catalogo de subdirecciones(areas) y un catalogo de subdirectores (usuarios-directivos), se relacionan de la siguiente forma:

Tabla lideres: id_usuario (pk)

Tabla subdirecciones: id_subdireccion (pk)

Tabla subdirectores: id_subdirector (pk), id_lider (Fk hacia lideres), id_subdireccion (Fk hacia subdirecciones)

en mi clase CatSubdirectores tengo las siguientes relaciones:

‘cat_subdirectores’ => array(self::BELONGS_TO, ‘CatSubdirecciones’, ‘id_subdireccion’),

‘cat_lideres’ => array(self::HAS_ONE, ‘CatLideres’, ‘id_usuario’),

con un objeto CDbCriteria intento crear una consulta que me traiga todos los subdirectores que existen en la tabla:

$criteria->select = 'cat_subdireccion.nombre as subdireccion,cat_lideres.apaterno as paterno, cat_lideres.amaterno as materno,cat_lideres.nombres as nombres, cat_subdirectores.id_subdirector,cat_subdirectores.activa ';

$criteria->with = array("cat_subdirectores","cat_lideres");

al ejecutar el programa aparece el siguiente error:

CDbCommand falló al ejecutar la sentencia SQL: SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘t.id_usuario’ in ‘on clause’

Por el error me doy cuenta que esta intentando llamar a id_usuario por medio de la tabla cat_subdirectores donde no existe ese campo, pero no entiendo porque lo intenta llamar con el alias t; lei que el alias t se le antepone a la tabla principal quien en este caso si no me equivoco es cat_subdirectores pero porque se lo antepone al campo id_usuario???


'cat_lideres' => array(self::HAS_ONE, 'CatLideres', 'id_usuario'),

en self::HAS_ONE, debese poner la fk de esa model que relacionase con la clave primaria de la relacion

para hacer lo que quieres debe hacer algo como


'cat_lideres' => array(self::HAS_ONE, 'CatLideres', '','on'=>'t.id=cat_lideres.id_usuario'),//cambia t.id por la clave primaria

o


'cat_lideres' => array(self::BELONGS_TO, 'CatLideres', 'id_usuario'),

Hola Gustavo, gracias por tu respuesta, hice lo siguiente:




'cat_lideres' => array(self::HAS_ONE, 'CatLideres', '' , 'on' => 't.id_lider = cat_lideres.id_usuario'),



Me funciono pero tuve que quitar del select una de las columnas, de lo contrario mandaba un error, al columna es: "cat_subdirecciones.nombre as subdireccion", al quitarla se muestra todo excepto el nombre de la subdireccion. El error que me muestra es el siguiente:

CDbCommand falló al ejecutar la sentencia SQL: SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘cat_subdirecciones.nombre’ in ‘field list’

con la otra linea de codigo que me sugeriste pasa lo mismo, solo que para que esta funcionara tuve que hacerle una pequeña modificacion, en la llave foranea:




'cat_lideres' => array(self::BELONGS_TO, 'CatLideres', 'id_lider'),



Me quede con la duda del on que usaste en la relacion, "supongo" que es el del join que se hace o me equivoco?, tienes alguna liga donde pueda consultar estas "opciones" que se pueden usar en las relaciones?

Muchas gracias por tu ayuda, Saludos!

aca esta un guia de referencia para las relaciones

http://www.yiiframework.com/doc/guide/1.1/es/database.arr

en este ultimo error, en el select debe usar lo nombre de la relacion y no lo nombre de la tabla, como "cat_subdirectores.nombre as subdireccion"

si, tas cierto, lo on es el del join

la forma mas cierta de hacer es la segunda que dije

Bueno que puede ayudarte

Saludos,

Gustavo

Muchas gracias Gustavo, cambie el nombre de la tabla por el nombre de la relacion y funcionó bien…

Muchas gracias de nuevo, bonito dia! :)

Hola otra vez,

En un formulario estoy dibujando un dropdownlist con el contenido de un catalogo de la bd, quize hacer la prueba traiendo los datos por medio de relaciones, y si pude pero al principio me marco un par de errores, lo cual me desconcertó porque pense que estaba entendiendo como se manejaba esto de las relaciones pero tal parece que me equivoque, les explico lo que intenté hacer en un pricipio:

Modelo CatImportancia => tiene la relacion:




'aplicaciones' => array(self::HAS_MANY, 'Aplicaciones', 'id_importancia'),



Modelo Aplicaciones => tiene la relacion




'cat_importancia' => array(self::BELONGS_TO, 'CatImportancia', 'id_importancia'),



hice la una funcion en el modelo Aplicaciones, donde trato de retraer los datos:




$cat = CatImportancia::model()->with(array(

		

			"cat_importancia"=>array(

			

				'Select'=>'id_importancia,descripcion',

				'condition'=>'t.activa="1"',

			),

			

		))->findAll();



Esto me mandaba un error: La relación "cat_importancia" no se encuentra definida en la clase active record "CatImportancia". ¿siempre debe existir el mismo nombre de variables de relacion entre los modelos que se estan relacionando?, porque para solucionar esto lo que hice fue cambiar el nombre de la relacion "aplicaciones" => "cat_importancia" (ambas relaciones, quedaron con el mismo nombre) y asi funcionó; luego quizé poner un "order" por la columna descripcion, y me manda un error de ambiguedad (en ambas tablas existe una columna con el mismo nombre), esto obviamente debe solucionarse con un alias, asi que puse cat_importancia.descripcion, supongo que aqui no hubo problemas porque solo son dos tablas pero ¿que pasa cuando hay mas de dos? todas las relaciones se tienen que nombrar igual? y si es asi como se resuelven las ambiguedades?

Gracias Por su ayuda.

como estas manejando la class CatImportancia en


$cat = CatImportancia::model()->with(array(

la relacion que existe en la model es ‘aplicaciones’, entonces lo ‘with’ deberia ser




$cat = CatImportancia::model()->with(array(

  "aplicaciones"=>array(



los nombres pueden ser diferentes, lo unico error que tinea era ese de la CatImportancia model no haber una relacion "cat_importancia"

y como dije, algunas veces lo nombre de las relaciones son las mismas entonces debe usar "alias"

el alias "t" es siempre lo de la model en uso

Gracias Gustavo, tienes razon estoy usando el modelo de CatImportancia, asi que cambie un poco el codigo:





$cat = $this->model()->with(array(

		

			"cat_importancia"=>array(

			

				'Select'=>'cat_importancia.id_importancia,cat_importancia.descripcion',

				'condition'=>'cat_importancia.activa="1"',

				'order'=>'cat_importancia.descripcion',

			),

			

		))->findAll();




De esta forma estoy haciendo referencia a la relacion que existe en mi modelo que es "Aplicaciones", ejecute esto y no me marcó ningun error, solo que la consulta no me trae filas, que mas estoy haciendo mal?

Salu2!

asi no se que debe ser

pero debe fijar lo sql generado por la query

para ver lo sql, en la config debe habilitar lo log y añadir a las configuraciones da base de datos




'preload'=>array('log'),

'components'=>array(

  'db'=>array(

 	//...

     'enableProfiling'=>true,

  ),

  //...

  'log'=>array(

 	'class'=>'CLogRouter',

 	'routes'=>array('class'=>'CWebLogRoute',)

  )

)



entonces verá lo log con lo sql generado, y despues podera fijar lo erro

Saludos,

Gustavo

Hola gustavo, espero me puedas ayudar (o alguien mas que sepa al respecto), estoy tratando nuevamente con las relaciones tengo una tabla principal (modelo) que se relaciona con 3 tablas(catalagos):

Aplicaciones <— Tabla principal

CatLenguajes <— Catalago

CatImportancia <— Catalago

CatSubdirecciones <— Catalago

en los catalagos tengo un id y una descripcion y lo quiero es obtener la descripcion usando ese id que se corresponde con un id en la tabla principal; tengo el siguiente query:




$r = Aplicaciones::model()->with(array(

			"cat_importancia"=>array(

			

				'Select'=>'cat_importancia.descripcion as importancia',

				'condition'=>'t.id_importancia=cat_importancia.id_importancia',

				

			),

			

			

			"cat_lenguajes" => array(

				'Select'=>'cat_lenguajes.descripcion as lenguaje',

				'condition'=>'t.id_lenguaje=cat_lenguajes.id_lenguaje',

			),

			

			"cat_subdirecciones"=>array(

				'Select'=>'cat_subdirecciones.nombre as subdireccion',

				'condition'=>'t.id_subdireccion=cat_subdirecciones.id_subdireccion',

			),

			

		))->findAll();



Cuando trato de imprimir el resultado solo me trae informacion sobre la tabla principal pero no las descripciones de los catalogos, intente cambiando los "condition" por un "on" pero resulta igual…

Gracias.