Yii Framework Forum: Relation Class Name Depending On Field Value - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Relation Class Name Depending On Field Value Dynamic relationship with same relationship name Rate Topic: -----

#1 User is offline   qlimax86 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 03-July 14

Posted 03 July 2014 - 10:34 AM

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...
0

#2 User is offline   le_top 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 366
  • Joined: 08-June 10
  • Location:France (Ile-de-France/Val d'Oise)

Posted 03 July 2014 - 01:35 PM

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))),
        );    }

0

#3 User is offline   alirz23 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 1,012
  • Joined: 08-August 12
  • Location:Durban, South Africa

Posted 03 July 2014 - 02:03 PM

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
0

#4 User is offline   le_top 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 366
  • Joined: 08-June 10
  • Location:France (Ile-de-France/Val d'Oise)

Posted 03 July 2014 - 02:42 PM

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

#5 User is offline   qlimax86 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 03-July 14

Posted 03 July 2014 - 03:09 PM

Thank you for your answers.

View Postalirz23, on 03 July 2014 - 02:03 PM, said:

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


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...
0

#6 User is offline   le_top 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 366
  • Joined: 08-June 10
  • Location:France (Ile-de-France/Val d'Oise)

Posted 03 July 2014 - 04:24 PM

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).
0

#7 User is offline   qlimax86 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 03-July 14

Posted 08 July 2014 - 07:40 AM

View Postle_top, on 03 July 2014 - 04:24 PM, said:

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!
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users