Relation Class Name Depending On Field Value

Hi everyone!

My question is about if this is possible:





 public function relations()

    {


        return array(

            'experience'=>array(self::HAS_ONE,ucfirst($this->getAttribute('exptype')).'Experience','uid')

        );

    }




and then call it like this:





echo $user->exptype;  //ehcoes Abcd


$user->experience;




It raises an error because it try to load Experience.php instead of AbcdExperience.php

Any suggestion why $this->exptype is null inside the relations method?

My workaround now is this




// defined more relations for different types,

// then call

$user->{$user->exptype.'_experience'}->....



Thank you very very much…

Maybe this code can inspire you.

This deals (partly) with the different cases where relations() are used and gets the real values only when they are available.

As long as the relations() method is called after fetching the specific record, you may be able to do what you which to do inside the relations.

Creating a method that does the same job is generally a better way.

My code below allow the use of the relation with complex conditions.




    public function relations()

    {

        if($this->getScenario()===null||$this->getScenario()===''||$this->getScenario()==='search') {

            $t=$this->getTableAlias(false,false);

            $ds=$this->getDbConnection()->getSchema();

            $lat=$ds->quoteColumnName("$t.lat");

            $lon=$ds->quoteColumnName("$t.lon");

        } else {

            $lat=CHtml::value($this->lat);

            $lon=CHtml::value($this->lon);

        }

        // NOTE: you may need to adjust the relation name and the related

        // class name for the relations automatically generated below.

        return array(

                'device' => array(self::BELONGS_TO, 'Devices', 'device_id','joinType'=>'INNER JOIN'),

                'areas' => array(self::HAS_MANY, 'GeoArea',array(),'scopes'=>array('contains'=>array($lat,$lon))),

        );    }



you would not be able to access the $this->getAttribute(‘attributename’) model has been initialized at that point basically the model object is not created

relations() is not called unless needed. So the model instance is ready under certain conditions.

Thank you for your answers.

That is what I thought too… Because I did a var_dump($this); inside the relations() method and the object seemed to be not initialized.

But this raises me another question:

why does echo $user->exptype; echoes the right value if the object is empty?

It seem that the relations() method is called on another object instance…

Test like this:

a. Keep the vardump inside ‘relations’ - to keep it simple do CVarDump::dump($this->attributes) .

b. Add a print statement just before your $user->experience (example: print "BEFORE CALL TO EXPERIENCE" ).

If the attributes are printed before the text printed in ‘b.’, the relations() are called before the call to ‘b.’ - my guess is that this is what happens for you.

I also think that if you do ‘$user=User::model()->findByPk(1)’ and then use ‘$user->experience’, that you might have some success in your endeavor (supposing that the user with primary key 1 exists).

I didn’t had time to make such test…

It’s a productive project.

I keep going with my "workaround" which I think is not too ugly

Thank you for all your answers!