Search code examples
phpyii2

migration to populate existing fields


I have a model and ready-made data in a table. In this model, I added a new field and made a connection with another table.

And in order not to manually fill in these fields for each record, I want to create a migration that will automatically fill in this field for all records.

Relationship table has two fields: post_id and author_id.

I'm creating a migration where I get all existing post_id and try to add value to author_id:

public function safeUp()
    {
        /**
         * @var Posts[] $posts
         */
        $posts = Posts::find()->all();
        foreach ($posts as $post) {
            $item = new PostAuthor();
            $item->setAttribute('post_id', $post->id);
            $item->setAttribute('author_id', 2);
            $item->save();
        }
    }

Now everything is working, and all existing posts are given an author_id with a value of 2.

But I would like to refine it a little, author_id can have a value from 1 to 4, and I want different values ​​​​to be added to each post in the migration.

Let's say the first post gets author_id: 1
The second post will get author_id: 1, author_id: 2
Third post author_id: 1, author_id: 2, author_id: 3
And the fourth post respectively author_id: 1, author_id: 2, author_id: 3, author_id: 4

But how can I do this, because now all my posts will receive the same values?

So far, the only working option I have is this one:

public function safeUp()
    {
        /**
         * @var Posts[] $posts
         */
        $posts = Posts::find()->all();

        if (isset($posts[1])) {
            $item = new PostAuthor();
            $item->setAttribute('post_id', $posts[1]->id);
            $item->setAttribute('author_id', 1);
            $item->save();
        }
        if (isset($posts[2])) {
            $item = new PostAuthor();
            $item->setAttribute('post_id', $posts[2]->id);
            $item->setAttribute('author_id', 1);
            $item->save();

            $item2 = new PostAuthor();
            $item2->setAttribute('post_id', $posts[2]->id);
            $item2->setAttribute('author_id', 2);
            $item2->save();
        }
        ....
    }

But in order to create for the first five records, there will be a lot of copying code, is it possible to do it all somehow differently??


Solution

  • If i understood it correctly, you want to create as many PostAuthors as the respective PostId.

    $posts = Posts::find()->all();
    
    foreach ($posts as $index => $post) {
        for($i = 0; $i < $index; $i++ ) {
            $item = new PostAuthor();
            $item->setAttribute('post_id', $posts->id);
            $item->setAttribute('author_id', $i+1);
            $item->save();
        }
    }