Laravel 4,如何为具有关系的表创建种子数据?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17390352/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel 4, how to I create seed data to tables with relationships?
提问by M?rten Cederman
I have created a database with two tables, "goals" and "partgoals". The practial use is to make a savings goal (money) and have milestones along the way (partgoals). I want the partgoals obviously be linked to a specific goal. The relationships are created but I run into trouble when trying to create my seed data.
我创建了一个包含两个表“目标”和“部分目标”的数据库。实际用途是制定储蓄目标(金钱)并在此过程中设定里程碑(部分目标)。我希望部分目标显然与特定目标相关联。关系已创建,但在尝试创建种子数据时遇到了麻烦。
My goal is to set up two goals table like this (GoalsTableSeeder.php):
我的目标是像这样设置两个目标表 (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 );
}
}
And my partgoals table like this (PartgoalsTableSeeder.php):
我的partgoals表是这样的(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 );
}
}
The migration table for "goals":
“目标”的迁移表:
<?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');
}
}
The migration table for partgoals:
部分目标的迁移表:
<?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');
}
}
What am I doing wrong? I am new to Laravel (and Laravel 4).
我究竟做错了什么?我是 Laravel(和 Laravel 4)的新手。
回答by clod986
I see a few problems with your code:
我发现您的代码存在一些问题:
1) The way you create the foreign key
When assigning the Foreign key constraint, you should make that column unsignedInteger
.
In the code below I will correct the mistake you made of naming two columns 'id'.
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) The way you seed your database
If you specify a foreign key, you should declare the value when creating the entry in the table seeder.
If you want to specify a NULL
value, this can be done by allowing the column to accept such value (by default it doesn't). In this case, we should add ->nullable()->default(NULL)
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();
});
Minor mistake
3) You are passing the 'id' => 1
twice in your seeder
小错误
3) 您'id' => 1
在播种机中通过了两次
回答by searsaw
When using increments
in the query builder, that automatically makes that your primary key, auto-incremented, and unique. You can't have a foreign key also be your primary key unless it's a one-to-one relationship. That's just bad design though. Your schema should look something like below.
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();
});
Also, when seeding, if you use the insertGetId
when inserting, it will return the ID of the record you just inserted. This you can use in another insert, like inserting into another table, later. However, this has to take place in the same script. You may be able to pass it back out to DatabaseSeeder
and then back into another seed script, but I haven't tried this.
此外,在播种时,如果您使用insertGetId
when inserting,它将返回您刚刚插入的记录的 ID。您可以稍后在另一个插入中使用它,例如插入到另一个表中。但是,这必须在同一个脚本中进行。您也许可以将它传回DatabaseSeeder
,然后再传回另一个种子脚本,但我还没有尝试过。
回答by Chris
I'm not familiar with Laravel, or what you're trying to do, but based on the error you added in the comments it seems that your problem is a result of trying to enter multiple records with the same primary key (1) into your partgoals
table.
我不熟悉 Laravel,也不熟悉您要做什么,但根据您在评论中添加的错误,您的问题似乎是由于尝试将具有相同主键 (1) 的多条记录输入到你的partgoals
桌子。
I'm not sure how you've set your tables up, but it seems like you've defined a partgoals
table with a unique primary key column ID
, which you're also trying to use as a foreign key to reference the goals
table. It may be worth creating another field to hold your foreign key in the partgoals
table.
我不确定您是如何设置表的,但您似乎定义了一个partgoals
具有唯一主键列的表ID
,您还试图将其用作外键来引用该goals
表。可能值得创建另一个字段来保存partgoals
表中的外键。
回答by Joel Fernandes
To seed tables with relationship, you need to defined model factories in the ModelFactory.php file and then create a seeder class to run the seeder.
要播种有关系的表,您需要在 ModelFactory.php 文件中定义模型工厂,然后创建一个播种器类来运行播种器。
For ex. 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
];
});
Then the seeder class can be as follows
那么播种机类可以如下
<?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());
}
});
}
}
You can refer this article on how to generate seeds for two tables with relationship http://deepdivetuts.com/seeding-two-tables-using-laravel-5-3
您可以参考这篇文章,了解如何为具有关系的两个表生成种子http://deepdivetuts.com/seeding-two-tables-using-laravel-5-3