1

我创建了一个包含两个表“goals”和“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

4 回答 4

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两次

于 2013-10-16T10:04:10.683 回答
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然后再传回另一个种子脚本,但我还没有尝试过。

于 2013-07-10T20:37:07.587 回答
0

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

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

于 2013-06-30T22:36:58.677 回答
0

要播种具有关系的表,您需要在 ModelFactory.php 文件中定义模型工厂,然后创建播种器类来运行播种器。

例如。模型工厂.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
    ];
});

那么seeder类可以如下

<?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

于 2017-01-27T00:49:02.207 回答