如何使用 Laravel Seeders和Eloquent模型填充数据样本

281 阅读2分钟

Laravel的Seeders是一些特殊的类,它们在Laravel项目的database/seeders 目录中,允许你以编程方式在数据库中插入默认或样本记录的集合。这个演示应用程序有一个播种机类,从应用程序文件夹根部的links.yml 文件中导入链接。

在你的代码编辑器中,打开以下文件。

database/seeders/LinkSeeder.php

它将包含以下代码。

database/seeders/LinkSeeder.php

<?php

namespace Database\Seeders;

use App\Models\Link;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Symfony\Component\Yaml\Yaml;

class LinkSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        //only import seeds if DB is empty.
        if (!Link::count()) {
            $this->importLinks();
        }
    }

    /**
     * Imports Links from the default links.yml file at the root of the app.
     * Change that file to import a set of personal basic links you want to show
     * as soon as the application is deployed.
     */
    public function importLinks()
    {
        $links_import_path = __DIR__ . '/../../links.yml';

        $yaml = new Yaml();
        if (is_file($links_import_path)) {
            $links = $yaml->parsefile($links_import_path);

            foreach ($links as $link) {
                DB::table('links')->insert([
                    'url' => $link['url'],
                    'description' => $link['description']
                ]);
            }
        }
    }
}

请注意,这段代码没有使用Link 模型,而是使用查询生成器在数据库中插入新的链接。这是一种在Laravel中处理数据库记录的不同方式,不依赖于Eloquent模型。即使这样做很好,通过使用Eloquent模型,你可以获得一系列有用的方法和捷径,使你的代码更简洁,更容易阅读。

为了改进这段代码,你将改变foreach 循环,使用Eloquent模型,而不是直接用查询生成器来查询数据库。你还要在循环开始之前创建一个默认的链接列表(在下面的代码中称为$default_list ),这样你就可以在每个新创建的链接中引用这个列表。

用下面的代码替换你的播种机类中的当前内容。

database/seeders/LinkSeeder.php

<?php

namespace Database\Seeders;

use App\Models\Link;
use App\Models\LinkList;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Symfony\Component\Yaml\Yaml;

class LinkSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        //only import seeds if DB is empty.
        if (!Link::count()) {
            $this->importLinks();
        }
    }

    /**
     * Imports Links from the default links.yml file at the root of the app.
     * Change that file to import a set of personal basic links you want to show
     * as soon as the application is deployed.
     */
    public function importLinks()
    {
        $links_import_path = __DIR__ . '/../../links.yml';

        $yaml = new Yaml();
        if (is_file($links_import_path)) {
            $links = $yaml->parsefile($links_import_path);

            $default_list = new LinkList();
            $default_list->title = "Default";
            $default_list->description = "Default List";
            $default_list->slug = "default";
            $default_list->save();

            foreach ($links as $link) {
                $seed_link = new Link();
                $seed_link->url = $link['url'];
                $seed_link->description = $link['description'];

                $default_list->links()->save($seed_link);
            }
        }
    }
}


更新后的代码使用了面向对象的方法来设置LinkListList 模型的属性,这些属性被 Eloquent 翻译成表列。for循环的最后一行使用对链接表的引用$default_list ,通过方法links() ,来保存该列表中的新链接。

完成后保存文件.Laravel播种机只会在数据库是空的时候运行, 以免与其他方式插入数据库的实际数据发生冲突.因此,为了运行修改后的播种机,你需要用artisan db:wipe 命令再次擦拭数据库。

运行下面的命令来擦除开发数据库。

docker-compose exec app php artisan db:wipe
OutputDropped all tables successfully.

现在要重新创建表并运行更新的播种机,你可以使用下面的artisan migrate --seed 命令。

docker-compose exec app php artisan migrate --seed

你应该收到与下面类似的输出。

OutputMigration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (124.20ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (121.75ms)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (112.43ms)
Migrating: 2020_11_18_165241_create_links_table
Migrated:  2020_11_18_165241_create_links_table (61.04ms)
Migrating: 2021_07_09_122027_create_link_lists_table
Migrated:  2021_07_09_122027_create_link_lists_table (112.18ms)
Seeding: Database\Seeders\LinkSeeder
Seeded:  Database\Seeders\LinkSeeder (84.57ms)
Database seeding completed successfully.