[RESUELTO??] Tablas con relaciones opcionales

Hola comunidad

Tengo un problema

tengo dos tablas relacionadas, pero la relacion es opcional

tabla matricula campo idEspecialidad opcional

tabla especialidades (idEspecialidad,descripcion)

cuando quiero mostrar los datos para modificarlos, si el campo tiene un valor, funciona todo bien

pero si esta vacio, me da error lo siguiente




<?php echo CHtml::activeTextField($model->especialidad,'descripcion',array('size'=>40,'readonly'=>'true')); ?>



sin embargo, cuando solamente muestro los datos (no es un form), no me da el error y muestra el campo vacio (como debe ser)




<td><?php echo CHtml::encode($model->especialidad->descripcion); ?></td>



probe poner el codigo anterior en el form y me da el mismo error

Podes mostrar el codigo completo de la vista?

y si podes del modelo tambien (la parte donde definis las relaciones)

y la parte del controlador donde llamas a esa vista…

Tengo una idea pero quiero corroborar…

el modelo




	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(

			'profesional' => array(self::BELONGS_TO, 'Rp_profesionales', 'pro_idProfesional','alias'=>'Rp_profesionales'),

			'titulo' => array(self::BELONGS_TO, 'Rp_titulos', 'tit_idTitulo','alias'=>'Rp_titulos'),

			'especialidad' => array(self::BELONGS_TO, 'Rp_especialidades', 'esp_idEspecialidad','alias'=>'Rp_especialidades'),

			'institucion' => array(self::BELONGS_TO, 'Rp_instituciones', 'ins_idInstitucion','alias'=>'Rp_instituciones'),

			'novedades' => array(self::HAS_MANY, 'Rp_novedades', 'mat_idMatricula'),

		);

	}



la vista




<div class="simple">

<?php echo CHtml::activeHiddenField($model,'esp_idEspecialidad'); ?>

<?php echo CHtml::activeLabelEx($model,'esp_idEspecialidad'); ?>

<?php echo CHtml::activeTextField($model->especialidad,'descripcion',array('size'=>40,'readonly'=>'true')); ?>

<?php echo CHtml::link(CHtml::image('images/aflist.gif','Lov'), '#', array('onclick'=>'lovEspecialidades()')); ?>

<?php echo CHtml::image('images/delete.png','Limpia', array('onclick'=>'limpia("Rp_matriculas_esp_idEspecialidad","Rp_especialidades_descripcion")')) ;?>

</div>



el controlador




	public function loadRp_matriculas($id=null)

	{

		if($this->_model===null)

		{

			if($id!==null || isset($_GET['id']))

				$this->_model=Rp_matriculas::model()->with('profesional.persona','titulo','especialidad')->findbyPk($id!==null ? $id : $_GET['id']);

			if($this->_model===null)

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

		}

		return $this->_model;

	}


	public function actionUpdate()

	{

		$model=$this->loadRp_matriculas();

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

		{

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

			if($model->save())

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

		}

		$this->render('update',array('model'=>$model));

	}


	public function actionCreate()

	{

		$model=new Rp_matriculas;

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

		{

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

			if($model->save())

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

		}

		$this->render('create',array('model'=>$model));

	}




<?php echo CHtml::activeTextField($model->especialidad,‘descripcion’,array(‘size’=>40,‘readonly’=>‘true’)); ?>

Con esto vas a tener varios problemas, el que comentas es uno.

$model->especialiad no existe si ESE $model no tiene una especialidad,

por lo tanto, el helper intenta acceder a una propiedad (‘descripcion’) de un objeto inexistente.

Ademas, suponiendo que la muestre, cuando guardas, esa descripcion no se guarda, ya que solo salvas

$model. ($model->especialidad es otro ActiveRecord y no es guardado)

Lo que te recomiendo es que veas esto:

How to use a single form to collect data for two or more models?

Nota que deberias modificar el create o el insert para que tenga en cuenta la relacion, es decir, deberias poner

manualmente el id de la relacion.

ok, lo hago a mano… :angry:

igual voy a intentar hacer un post en ingles para que "the master qiang" lo vea, jeje

porque es raro que en un form no funcione y en una vista si

se supone que esta haciendo un outer join con la tabla Especialidades y si no existe el idEspecialidad, la descripcion deberia ser "vacia"

con respecto al insert y update, el campo es read only porque los valores los saco de una LOV (Lista de Valores: algo parecido a dropdownlist o CAutocomplete, pero distinto, ja) que me retorna el Id y la descripcion y al momento de grabar, solo se tiene en cuenta el Id

saludos y gracias por contestar siempre

Ahora hiciste un poco más clara la pregunta en el foro en ingles!!!

Bien!

El problema es ese que te dije, los CHtml::active*() tratan de llenar el campo con el valor de la base. En tu caso, como $model->especialidad no existe, es enviado algo que NO es un objeto al CHtml::activeYextField(), el active text field ESPERA un objeto, para poder acceder a la propiedad que le pasas como parametro (en tu caso ‘descripcion’) ahí es donde surge el problema.

Tal vez seria mejor si usas un condicional:

if (!empty($model->especialidad))

echo Chtml::active…

ok, hay que trabajar con un atributo "auxiliar",

agrego un atributo al modelo




   public $descripcion_especialidad;



despues en loadRp_matriculas




public function loadRp_matriculas($id=null)

        {

                if($this->_model===null)

                {

                        if($id!==null || isset($_GET['id']))

                                $this->_model=Rp_matriculas::model()->with('profesional.persona','titulo','especialidad')->findbyPk($id!==null ? $id : $_GET['id']);

                        if($this->_model===null)

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

                $this->_model->descripcion_especialidad = $this->_model->especialidad->descripcion;

                }

                return $this->_model;

        }




en la vista




<?php echo CHtml::activeTextField($model,'descripcion_especialidad',array('size'=>40,'readonly'=>'true')); ?>



Pero estaria bueno que esto lo maneje el framework !!!!!!!

PD: me expreso mejor en ingles que en castellano!!! jajaj

Gracias PoL

hOla horacio!

Si, estaria bueno que el framework lo qnalice y lo hace. ESA es la razón por la que tira el error. Porque es null. El problema es que el nombre del components HTML depende de la class del modelo que es lo que vos pasas.

Saludos!

Hola

nada como dejar pasar un día y encarar el problema nuevamente

otra solucion, un poco mas facil

Para todas las relaciones opcionales:

si el campo es null…

                    if (&#036;this-&gt;_model-&gt;especialidad==null){


                        &#036;this-&gt;_model-&gt;especialidad=new Rp_especialidades;


                    }

y todo ok

:lol: :lol: :lol:




    public function loadRp_matriculas($id=null)

    {

        if($this->_model===null)

        {

            if($id!==null || isset($_GET['id']))

               $this->_model=Rp_matriculas::model()->with('profesional.persona','titulo','especialidad')->findbyPk($id!==null? $id : $_GET['id']);

            if($this->_model===null)

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

                        if ($this->_model->especialidad==null){

                            $this->_model->especialidad=new Rp_especialidades;

                        }

        }

        return $this->_model;

    }




el amigo tri

encontro esto

http://www.yiiframew…ml#value-detail

si el objeto no existe no da error




<?php echo CHtml::value($model,'especialidad.descripcion'); ?>



saludos