Yii Webservice - Relations

Hi everyone.

This is my first post in forum, and i wold like to thank all Yii developers for this awesome framework.

I’m having a little problem creating a webservice and retrieving object related models.

Here is my code:

Inscricao.php:




class Inscricao extends CActiveRecord

{

	/** @soap @var integer */ public $id;

	/** @soap @var string */ public $nome;

	/** @soap @var Curso */ public $curso;

	

	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(

                       'curso' => array(self::BELONGS_TO, 'Curso', 'id_curso'),

                 );

	}


    ...


}



Curso.php




class Curso extends CActiveRecord

{

    /** @soap @var string */ public $nome;


    ...

}



SoapController.php:




class SoapController extends CController

{

	

    public function actions()

    {

        return array(

            'inscricao'=>array(

                'class'=>'CWebServiceAction',

                'classMap'=>array(

                	'Curso'=>'Curso',

                	'Inscricao'=>'Inscricao',

                ),

            ),

        );

    }


	

    /**

	 * @param string

     * @return Inscricao[]

     * @soap

     */

    public function getInscricoes()

    {

	return Inscricao::model()->findAll();

    }

	

}



Ad when i call:

$client = new SoapClient(Yii::app()->createAbsoluteUrl(‘soap/inscricao’));

$model = $client->getInscricoes();

$model->curso is NULL

Someone can help me?

Thx u!

No one?

getInscricoes() returns an array of models, so:




$client = new SoapClient(Yii::app()->createAbsoluteUrl('soap/inscricao'));

$models = $client->getInscricoes();


foreach($models as $model)

{

  echo $model->curso->nome;

}



Also use with() to reduce database queries:




    public function getInscricoes()

    {

        return Inscricao::model()->with('curso')->findAll();

    }



Tnx for u reply Tsunami.

The problem is that $model->curso return NULL, i can’t access $model->curso->nome

I solved the problem doing:




foreach($model as $m)

    $m->curso = $m->getRelated('curso');



But i have many others relations and i don’t want to do this for each one, i feel this is not the correct way of doing this…

Same problem here.

When we declare the public attribute for the SOAP web service with the same name as the relation, we kind of mess up the model, resulting in the attribute always returning NULL…

You shouldn’t and can’t use ActiveRecords on the client side of a web service. All classes that are supposed to be used on the client side should have all their properties filled with data.

To get a better image of this let’s assume that the SOAP call can only pass arrays around. An object can be converted to an array by reading all of its public properties. If a property value is an object, it has to be converted to an array the same way.

Relations in ActiveRecords are not properties. They are accesses like properties but magic methods are used for this. SOAP has no magic :slight_smile:

Unfortunately you have to use wrapper objects and rewrite data from ActiveRecords into them before returning.

Maybe it’s a stupid observation, but I didn’t see the @var Id in your Curso.php, if it’s not there, you have to modify your database table with that column and modify your Curso.php.

@nineinchnick Ok, maybe I should have read the initial post better, and my question should probably go to another thread.

I was actually writing about the model server-side.




// If my model is (1-N relation between Foo and Bar) :

class Foo extends CActiveRecord {


	/**

	 * @var Bar[]  bars {nillable=false, minOccurs=1, maxOccurs=unbounded}

	 * @soap

	 */

	public $bars;

	

	// ...


	public function relations() {

		return array(

			'bars' => array(self::HAS_MANY, 'Bar', 'id_foo'),

		);

	}


	// ...


}


// then 

var_dump($foo->bars);

// always returns NULL, event if there actually are some related models in the database



Ok, I open a new thread…