User values from two tables

Hi there :)

I have two groups of users: clients and members.

The authentication checks username and password against the (parent-)table ‘user’. Additional information is stored in the table ‘client’ or ‘member’. The table ‘user’ has a row with the key ‘role’ with the value ‘client’ or ‘member’, refering to either one of the tables.

The tables client and member have a row user_id, with the id of the corresponding user.id.

My relations are as follows:


/**

 * Model User

 */

class User extends CActiveRecord

{

	// [...]

	public function relations()

	{

		// Every user has only one related table, either client or member

		return array(

			'client' => array(self::HAS_ONE, 'Client', 'user_id'),

			'member' => array(self::HAS_ONE, 'Member', 'user_id'),

		);

	}	

}


/**

 * Model Member

 */

class Member extends CActiveRecord

{

	// [...]

	public function relations()

	{

		// Every member belongs to one user

		return array(

			'member' = >array(self::BELONGS_TO, 'User', 'user_id'),		

		);

	}	

}


/**

 * Model Client

 */

class Client extends CActiveRecord

{

	// [...]

	public function relations()

	{

		// Every client belongs to one user

		return array(

			'client' => array(self::BELONGS_TO, 'User', 'user_id'),

		);

	}	

}

Is this correct so far?

And how would I then access the additional information from let’s say the table client?


$user = User::model()->findByAttributes(array('username' => $this->username));

print_r($user->client);

doesn’t seem to work. I get an object with only the values from the table user.

Best regards

ycast

Not sure if you are familiar with the giix extension or not or if you are even interested but the crud generator in giix will generate this for you. Look in the generated views for $relatedModel and adjust to your needs.


class User extends CActiveRecord

{

// [...]

public function relations()

{

// Every user has only one related table, either client or member

return array(

'client' => array(self::HAS_ONE, 'Client', 'user_id'),

'member' => array(self::HAS_ONE, 'Member', 'user_id'),

);

}

}

I think this code should be:


class User extends CActiveRecord

{

// [...]

public function relations()

{

// Every user has only one related table, either client or member

return array(

'client' => array(self::HAS_MANY, 'Client', 'user_id'),

'member' => array(self::HAS_MANY, 'Member', 'user_id'),

);

}

}

Thank you guys, I missed something in my database design that’s why it wasn’t working as expected.

I now use following code and am wondering if this is the best way to do it:


// Retrieve additional information of current user

// from on of the related tables (member, client, admin)

if ($user->role == 'client') 

{

    $this->setState('info', $user->client);

} 

else if ($user->role == 'member') 

{

    $this->setState('info', $user->member);

} 

else if ($user->role == 'admin') 

{

    $this->setState('info', $user->admin);

}

I can then access the additional information with (for example):


Yii::app()->user->info->street

Any comments on this? :)

Addition:

Instead of the above code to retrieve the corresponding additional information I could use this shortcut instead:


$this->setState('info', $user->{$user->role}); // {user->role} == e.g. 'client'

But it isn’t very transparent.