我创建了一个包含两个表的数据库,“目标”和“部分目标”。实际用途是制定一个储蓄目标(金钱)并在此过程中有里程碑(部分目标)。我希望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)的新手。
答案 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
的表生成种子