Lets say I have a table 'account' with below structure
CREATE TABLE IF NOT EXISTS `account` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Id',
`name` varchar(255) NOT NULL COMMENT 'Name',
`index` int(11) NOT NULL COMMENT 'Index',
`user_id` int(11) NOT NULL COMMENT 'UserID',
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`)
)
I have created a model 'Account' for that using gii.
When I try create new account, I want user_id
to be assigned from session
So, In the controller, I tried like below.
$model = new Account();
$model->**setUser_Id**(Yii::$app->user->getID());
if ($model->load(Yii::$app->request->post()) && $model->save())
But, I don't write any setUser_Id
method in Account model, since I assumed when I call set methods, it will automatically assign the property of ActiveRecord.
But its throwing error. But it works fine when I try
$model->user_id = Yii::$app->user->getID();
As per documentation http://www.yiiframework.com/wiki/167/understanding-virtual-attributes-and-get-set-methods/, Note that the get/set functions can be called directly as functions (but requiring the usual function-call parentheses):
$x = $model->fullname;
$x = $model->getFullname(); // same thing
$model->active = 1;
$model->setActive(1); // same thing
Can you experts throw some light on this please?
[edit] read the question a bit better and did few clarifications to make the answer more comprehensive.
The exception is actually expected.
The way the whole virtual attributes functionality has been implemented in Yii shows that when calling $model->attribute
the magic methods __get()
and __set()
search for the attribute name in the table columns, and if not, search for the getter or setter, respectively, that you might have implemented. (That's very approximate but should give you the idea, more information can be seen by looking at the code: https://github.com/yiisoft/yii2/blob/master/framework/db/BaseActiveRecord.php#L237)
This means that the virtual attributes work only one way natively. Otherwise you can always access them via a direct method call using $model->getAttribute('my_attribute');
and $model->setAttribute('my_attribute', $value);
The example you're taking from the link you posted is out of context (apart having been written for Yii 1): in there you get the getter/setter implemented manually and later called in both ways.
The only case where names might not be coherent with what you have in the database is when the table name contains underscores, in which case they'll be removed: e.g. people_manager
becomes PeopleManager
as class name for the model.
It's not anyway clear what you're trying to achieve, this might help us give you a better direction on how to achieve what you want.
It is correct that it throws an exeception, because you have not written any setter or getter. ActiveRecord in yii implementation uses virtual attributes (implemented via __get()/__set() magic function), which can be accessed like $model->attribute and $model->attribute = $value. You can not use $model->getAttribute() or $model->setAttribute($value), until you implement them yourself.
Your problem is because PHP is case-sensitive about user-defined identifiers. When you use $model->user_id
then you should call $model->setUser_id
and not $model->setUser_Id
or $model->setUserId
, etc. I mean, only the first letter after set is capital and the rest is as the field name. Let me now if this answer solved your problem.