A
A
Agronya2015-06-13 18:03:54
Yii
Agronya, 2015-06-13 18:03:54

How to read ActiveRecord attributes in Yii2?

Good day. I decided to rewrite my new project from Yii 1.1 to Yii 2. There was a problem, I don't know what I'm doing wrong.
Let's say I get a model from the database and want to get its attribute, let it be the "name" field.
In Yii 1.1 it would be something like this:
$user = User::model()->findByPk(1);
echo $user->name;
In Yii 2.2, I'm trying to do it like this:
$user = User::findOne(1);
echo $user->name;
I get NULL in response. What is typical, if the name attribute is set to private instead of public, then everything works. Although it should be the other way around.
The $user->getAttribute('name') option also works, but there is no desire to write such a construct every time.
I read on stackoverflow that you need to define rules for model attributes.
Thanks in advance for your help :)
Class code:

<?php

namespace app\models;

class User extends \yii\db\ActiveRecord implements \yii\web\IdentityInterface
{
    public $id;
    public $service;
    public $service_id;
    public $name;
    public $avatar_url;
    public $auth_key;
    public $add_time;
    public $update_time;
    public $setting_safe_search = 1;
    public $setting_only_good_video_quality = 1;
    public $service_friends;

    public static function tableName()
    {
        return '{{%users}}';
    }

    public function rules() {
        $result = array(
            // Обязательные поля
            ['auth_key', 'required'],
            [['id', 'service_id', 'add_time', 'update_time'], 'integer'],
            ['name', 'string', 'max' => 80],
            [['setting_safe_search', 'setting_only_good_video_quality'], 'boolean']
        );
        return $result;
    }

    public function getId()
    {
        return $this->id;
    }

    public function getAuthKey()
    {
        return $this->auth_key;
    }
    public function validateAuthKey($authKey)
    {
        return $this->auth_key === $authKey;
    }

    public static function findIdentity($id)
    {
        return self::findOne($id);
    }
    public static function findIdentityByAuthKey($auth_key)
    {
        return self::find()->where(['auth_key' => $auth_key])->one();
    }
    public static function findIdentityByAccessToken($token, $type = null)
    {
        foreach (self::$users as $user) {
            if ($user['accessToken'] === $token) {
                return new static($user);
            }
        }

        return null;
    }

    public function getServiceNameById($id)
    {
        switch($id)
        {
            case 1:
                return 'vkontakte';
                break;
            default:
                return NULL;
                break;
        }
    }
    public function beforeValidate()
    {
        if($this->isNewRecord)
        {
            $this->auth_key = rand_string(30);
        }
        return parent::beforeValidate();
    }
    public function updateSocialInfo()
    {
        $info = VK::instance()->getInfo($this->service_id);
        $this->name = $info->first_name . ' ' . $info->last_name;
        $this->avatar_url = $info->photo_medium;
        $this->service_friends = VK::instance()->getFriends($this->service_id);
        $this->save();
    }

    public function beforeSave($insert) {
        $time = time();
        $this->service_friends = serialize($this->service_friends);
        if($this->isNewRecord) {
            $this->add_time = $time;
        }
        $this->update_time = $time;
        return parent::beforeSave($insert);
    }
    public function afterSave($insert, $changedAttributes)
    {
        $this->service_friends = unserialize($this->service_friends);
    }
    public function afterFind ()
    {
        $this->service_friends = unserialize($this->service_friends);
        return parent::afterFind();
    }
}

Answer the question

In order to leave comments, you need to log in

[[+comments_count]] answer(s)
A
Agronya, 2015-06-13
@Agronya

Found the answer here:

Note: The Active Record attributes are named after the associated table columns in a case-sensitive manner. Yii automatically defines an attribute in Active Record for every column of the associated table. You should NOT redeclare any of the attributes.

F
fatal_project, 2016-04-02
@fatal_project

all the salt in the public properties of the corresponding fields of the database table - that's the problem.
if we go deeper, in the first yii the _attributes property of the ActiveRecord model was initially initialized in the constructor with the fields of the corresponding table from the database, so the presence or absence of properties in the model did not affect the behavior of certain yii methods.
in the second yii the situation is slightly different. _attributes is always empty and is not initialized anywhere by default. if you set public properties of the corresponding table fields in the model, then just a banal assignment $model->$attrName = $attrValue will occur, while _attributes will always be empty and not initialized, and as a result, the result is higher.
if you remove these properties, then through the magic method __set yii2 will do everything as it should and the _attributes property will be initialized as expected and the model will start working as the developer expects.
I myself could not understand for a long time what happened when I started to transfer projects to yii2. the search for information has led to a dead end, there are many situations, there are no answers. I had to figure it out, I hope my answer will help someone understand their mistakes.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question