Laravel 4:处理种子中的关系

Posted

技术标签:

【中文标题】Laravel 4:处理种子中的关系【英文标题】:Laravel 4: Working with relationships in seeds 【发布时间】:2013-01-17 22:40:21 【问题描述】:

在 L4 的新种子功能中是否有一种简单的方法来管理多对多关系?

一种方法是为数据透视表制作种子,但我会做很多工作。

对这类事情的良好工作流程有什么想法吗?

【问题讨论】:

【参考方案1】:

种子用于简单信息、测试数据和静态信息。我不建议用它来处理关系。就个人而言,我只将它用于每个表的 2 或 3 条记录,以帮助测试我的应用程序。

在开发应用程序时,请考虑先处理数据输入(管理)区域,然后再处理前端。这样您就可以轻松添加测试数据。

【讨论】:

我同意,但即使您可以轻松输入数据,播种仍然很重要且很有帮助。因此,除非您有某种方法可以将管理员输入转换为种子,否则这真的回答了我的问题吗?【参考方案2】:

Laravel 种子文件是常规的 php 脚本(除了它们需要返回一个数组)。您可以在种子文件中查询数据库(使用 Eloquent、Fluent builder 甚至 PDO)。

解决多对多问题的一种方法是故意命名您的种子文件,以便最后填充数据透视表...例如,您可以在文件名前添加一个数值(即 1_authors.php 、2_books.php、3_authors_books.php 等)。 Artisan 在执行之前按字母顺序对文件名进行排序。

我已经在 Laravel 4 database seeding 上发布了一个小教程 - 这应该可以帮助您继续前进。另外,您可以通过seeding查阅官方文档。

【讨论】:

【参考方案3】:

在最新版本的 Laravel 4 中,您可以在 DatabaseSeeder 类的“运行”方法中定义所有播种器脚本的运行顺序。

public function run()

    DB::statement('SET FOREIGN_KEY_CHECKS=0;');

    $this->call('PrimaryTableOneSeeder');
    $this->command->info('The first primary table has been seeded!');

    $this->call('PrimaryTableTwoSeeder');
    $this->command->info('The second primary table has been seeded!');

    $this->call('PivotTableSeeder');
    $this->command->info('The pivot table has been seeded!');

    DB::statement('SET FOREIGN_KEY_CHECKS=1;');

您会注意到我在运行所有种子之前和之后禁用了外键约束。这可能是不好的做法,但这是我可以使用 truncate 函数重新设置每个表的 id 计数的唯一方法。如果您遵循inserting related models 上的指南,则可能不需要这种做法。

class PrimaryTableOneSeeder extends Seeder 

public function run()

    DB::table('primaryone')->truncate();
    Primaryone::create(array(
        'field' => 'value',
        'created_at' => new DateTime,
        'updated_at' => new DateTime
    ));

要像我在示例中所做的那样使用mass assignment 以及最新版本的文档所做的那样,您需要为模型指定一些受保护的或可填充的列。为此,只需将属性添加到您的模型中,如下所示:

class Primaryone extends Eloquent 

protected $guarded = array('id');

【讨论】:

我会说这几乎是正确的答案。如果我是你,我不会禁用外键检查。可以讨论是否也可以截断表格。我不会这样做,但这只是我。原因是 db:seed 可以随时运行,这意味着数据库中可能包含重要数据。 @AndHeiberg 这是一个很好的观点。每个人都不知道种子不是用于生产,而是用于使用测试数据为开发数据库播种,如果它被截断就可以了。生产数据应通过应用程序自己的接口或通过 ssh db 连接添加。 有没有兼容sqlite的方法? SET FOREIGN_KEY_CHECKS 触发 sqlite 错误。这就是我的问题的根源:我一直在为 dev 使用 quickie sqlite db,现在正试图转移到 postgres,却发现 sqlite 的宽大处理隐藏了许多问题。 @CJThompson - 抱歉回复晚了。我对 sqlite 的解决方案是完全销毁/重新创建数据库。对于单元测试,我有一个空的 sqlite 数据库和一个完全种子数据库,我在测试之前克隆了它。 PostgreSQL 解决方案怎么样? SET FOREIGN_KEY_CHECKS 也会在 PostgreSQL 中触发错误。

以上是关于Laravel 4:处理种子中的关系的主要内容,如果未能解决你的问题,请参考以下文章

Laravel:种子表有几个属于使用工厂的关系

如何使用 laravel 迁移和种子正确处理数据库数据更改

Laravel 4 db 种子特定播种器文件

尝试访问 Laravel 4 中的关系数据时出错

laravel 4中的一对多关系帮助

Laravel 4 中的多个身份验证会话