Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding an attribute to yii2 active record model that is not in database

I have a mySQL database that has a table videos and two columns, start_time and end_time, which are in the format 2017-01-24 15:38:11.

I have an active record model Videos that extends \yii\db\ActiveRecord and i would like to add a few additional attribute that are not in the database.

I am trying to split the time stamp into a separate date and time that i can then display as columns in my gridview widget. I successfully did this by setting the column values directly in the view to functions with something like this...

<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel'  => $searchModel,
    'columns' => 
    [
        [
        'class' => '\kartik\grid\DataColumn',
        'attribute' => 'videodate',
        'value' =>  function($model)
            {
                $datetime = new DateTime('start_time');
                $date = $datetime->format('Y-m-d');
                return $date;
            },
        ],  
    ],
    'responsive'=>true,
    'hover'=>true
]); ?>

However this is less than ideal as i would like to be able to utilize the date and time as attributes in my videoSearch model for filtering and sorting.

From my research i have added the attribute to the Video model in both my rules() and attributeLabel() functions however am unsure of how to set the value. My initial thought was to do it like a relation...

public function getVideodate(){
    $datetime = new DateTime('start_time');
    $date = $datetime->format('Y-m-d');
    return $date;
}

However this does not yield the desired results. I figured if i can get it defined and set in the model then adding it to the search model should be simple were as my temporary solution (in the view) complicated this significantly.

I intend to use kartik's daterange and time filters on his improved gridview widget. Thanks ahead and please let me know what else i can include.

Nick

like image 263
Nick R Avatar asked Jan 25 '17 22:01

Nick R


People also ask

What is ActiveRecord in Yii2?

ActiveRecord is the base class for classes representing relational data in terms of objects. Active Record implements the Active Record design pattern. The premise behind Active Record is that an individual yii\db\ActiveRecord object is associated with a specific row in a database table.

What is active query in Yii2?

An ActiveQuery can be a normal query or be used in a relational context. ActiveQuery instances are usually created by yii\db\ActiveRecord::find() and yii\db\ActiveRecord::findBySql(). Relational queries are created by yii\db\ActiveRecord::hasOne() and yii\db\ActiveRecord::hasMany().

Is null in Yii2 query?

Yii2 will use "IS NULL" if the $values === null , but in case the value is supplied as an array, and one of those array elements is null, it will not get any special treatment, resulting in the query never matching any records with NULL value.

How to delete Record in Yii2?

Deleting Data You can call yii\db\ActiveRecord::deleteAll() to delete multiple or all rows of data.


1 Answers

In your model define virtual variables

class Video extends \yii\db\ActiveRecord {

    public $video_date; // defining virtual attribute
    public $video_time; // defining virtual attribute

    public function rules()
    {
        return [
            // other rules ...
            [['video_date', 'video_time'], 'safe'],
        ];
    }

    // this method is called after using Video::find()
    // you can set values for your virtual attributes here for example
    public function afterFind()
    {
        parent::afterFind();

        $datetime = new DateTime('start_time');

        $this->video_date = $datetime->format('Y-m-d');
        $this->video_time = $datetime->format('H:i:s');
    }

    // this method is called right before inserting record to DB
    // after calling save() on model
    public function beforeSave($insert)
    {
        if (parent::beforeSave($insert)) {
            if ($insert) {
                // if new record is inserted into db
            } else {
                // if existing record is updated
                // you can use something like this 
                // to prevent updating certain data
                // $this->status = $this->oldAttributes['status'];
            }

            $this->start_time = $this->video_date . ' '. $this->video_time;

            return true;
        }

        return false;
    }

}

In view you then use video_date / video_time as attribute, also you might want to add attribute labels to model too.

like image 91
Ripper Avatar answered Oct 29 '22 19:10

Ripper