Laravel 4,如何为具有关系的表创建种子数据?

时间:2013-06-30 12:26:53

标签: database foreign-keys laravel laravel-4 seeding

我创建了一个包含两个表的数据库,“目标”和“部分目标”。实际用途是制定一个储蓄目标(金钱)并在此过程中有里程碑(部分目标)。我希望partgoals显然与特定目标相关联。创建关系但在尝试创建种子数据时遇到了麻烦。

我的目标是设置两个这样的目标表(GoalsTableSeeder.php):

<?php

class GoalsTableSeeder extends Seeder {

    public function run()
    {
        DB::table('goals')->delete();


        $goals = array(
            array(
                'max'      => 1850000,
                'avgsav' => 3500,
                'duedate'  => date('2015-03-15'),
                'created_at' => new DateTime,
                'updated_at' => new DateTime,
            ),
            array(
                'max'      => 1100000,
                'avgsav' => 5000,
                'duedate'  => date('2013-11-15'),
                'created_at' => new DateTime,
                'updated_at' => new DateTime,
            )
        );

        DB::table('goals')->insert( $goals );
    }

}

我的分区表就像这样(PartgoalsTableSeeder.php):

<?php

class PartgoalsTableSeeder extends Seeder {

    public function run()
    {
        DB::table('partgoals')->delete();


        $partgoals = array(
            array(
                'id' => 1,
                'milestone'      => 100000,
                'duedate'  => date('2014-03-15'),
                'created_at' => new DateTime,
                'updated_at' => new DateTime,
            ),
            array(
                'id' => 1,
                'milestone'      => 20000,
                'duedate'  => date('2013-06-15'),
                'created_at' => new DateTime,
                'updated_at' => new DateTime,
            ),
            array(
                'id' => 2,
                'milestone'      => 400000,
                'duedate'  => date('2013-09-15'),
                'created_at' => new DateTime,
                'updated_at' => new DateTime,
            ),
            array(
                'id' => 2,
                'milestone'      => 200000,
                'duedate'  => date('2014-10-15'),
                'created_at' => new DateTime,
                'updated_at' => new DateTime,
            )
        );

        DB::table('partgoals')->insert( $partgoals );
    }

}

“目标”的迁移表:

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateGoalsTable extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('goals', function(Blueprint $table)
        {
            $table->increments('id');
            $table->integer('max');
            $table->float('avgsav');
            $table->date('duedate');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('goals');
    }

}

部分目标的迁移表:

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreatePartgoalsTable extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('partgoals', function(Blueprint $table)
        {
            $table->foreign('id')
                ->references('id')->on('goals')
                ->onDelete('cascade');
            $table->increments('id');
            $table->float('milestone');
            $table->date('duedate')->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('partgoals');
    }

}

我做错了什么?我是Laravel(和Laravel 4)的新手。

4 个答案:

答案 0 :(得分:4)

我发现您的代码存在一些问题:

1)创建外键的方式
分配外键约束时,应该使该列unsignedInteger 在下面的代码中,我将更正您在命名两列'id'时所犯的错误。

Schema::create('partgoals', function(Blueprint $table)
    {
        $table->increments('id');        
        $table->unsignedInteger('goal_id');
        $table->foreign('goal_id')
            ->references('id')->on('goals')
            ->onDelete('cascade');
        $table->float('milestone');
        $table->date('duedate')->nullable();
        $table->timestamps();
    });


2)您为数据库设定种子的方式
如果指定外键,则应在表播种器中创建条目时声明该值。
如果要指定NULL值,可以通过允许列接受此值来实现(默认情况下不会)。在这种情况下,我们应该添加->nullable()->default(NULL)

Schema::create('partgoals', function(Blueprint $table)
    {
        $table->increments('id');        
        $table->unsignedInteger('goal_id')->nullable()->default(NULL);
        $table->foreign('goal_id')
            ->references('id')->on('goals')
            ->onDelete('cascade');
        $table->float('milestone');
        $table->date('duedate')->nullable();
        $table->timestamps();
    });

轻微错误
3)您在播种机中两次传递'id' => 1

答案 1 :(得分:1)

在查询构建器中使用increments时,会自动将其作为主键,自动增加且唯一。除非是一对一的关系,否则您不能将外键作为主键。那只是糟糕的设计。您的架构应如下所示。

Schema::create('partgoals', function(Blueprint $table)
    {
        $table->increments('id');
        $table->foreign('goal_id')
            ->references('id')->on('goals')
            ->onDelete('cascade');
        $table->float('milestone');
        $table->date('duedate')->nullable();
        $table->timestamps();
    });

此外,播种时,如果在插入时使用insertGetId,则会返回刚刚插入的记录的ID。这可以在另一个插入中使用,例如稍后插入另一个表。但是,这必须在同一个脚本中进行。您可以将其传递回DatabaseSeeder然后再返回另一个种子脚本,但我还没有尝试过。

答案 2 :(得分:0)

我不熟悉Laravel,或者您正在尝试做什么,但根据您在评论中添加的错误,您的问题似乎是尝试使用相同的主键输入多个记录( 1)进入partgoals表。

我不确定您是如何设置表格的,但似乎您已经定义了一个partgoals表,其中包含唯一的主键列ID,您也在尝试用作外键来引用goals表。可能值得创建另一个字段来将外键保存在partgoals表中。

答案 3 :(得分:0)

要使用关系对表进行种子处理,您需要在ModelFactory.php文件中定义模型工厂,然后创建一个播种器类来运行播种器。

对于前。 ModelFactory.php

$factory->define(App\Category::class, function (Faker\Generator $faker) {

    $name = $faker->name;

    return [
        'name' => $name,
        'visible' => 1
    ];
});

$factory->define(App\Video::class, function (Faker\Generator $faker) {

    return [
        'title' => $faker->name,
        'description' => '',
        'status' => 1
    ];
});

然后播种者类可以如下

<?php

use Illuminate\Database\Seeder;

class CategoriesTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $categories = factory(App\Category::class, 20)->create()->each(function ($u) {
                for ($i=0; $i<5; $i++)
                {
                    $u->videos()->save(factory(App\Video::class)->make());
                }
            });
    }
}

您可以参考这篇文章,了解如何为两个关系为http://deepdivetuts.com/seeding-two-tables-using-laravel-5-3

的表生成种子