我是laravel的新手。我正在做一个项目,用户首先注册,他的信息将存储在用户表中。然后他或她登录网站,用户将提供另一个注册表格作为献血者。这个信息将存储另一个表,即 blooddonners table.so我想在 blooddonner 表中创建一个外键。foreingn键将是 id 来自用户表。这就是为什么我为 blooddonner 表创建了一个迁移,
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateBlooddonnerTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('blooddonners', function(Blueprint $table)
{
$table->increments('id');
$table->unsignedInteger('donner_id');
$table->foreign('donner_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade');
$table->string('donner_name');
$table->string('email')->unique();
$table->string('blood_group');
$table->string('phone_number')->unique();
$table->string('location');
$table->date('date_of_birth');
$table->date('last_date_of_donation');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('blooddonners');
}
}
但在提交表格后,我面临以下错误,
Illuminate \ Database \ QueryException
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`needa`.`blooddonners`, CONSTRAINT `blooddonners_donner_id_foreign` FOREIGN KEY (`donner_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE) (SQL: insert into `blooddonners` (`date_of_birth`, `blood_group`, `location`, `email`, `phone_number`, `last_date_of_donation`, `updated_at`, `created_at`) values (2014-08-06, A-, SHERPUR, raihn_cse@yahoo.com, 01796580404, 2014-08- 20, 2014-08-10 19:42:38, 2014-08-10 19:42:38))
虽然我在Laravel中很新,所以我有疑问,我在迁移文件中设置外来的方式,是设置外键的方法吗?,导致错误与该外键有关。 / p>
答案 0 :(得分:1)
您设置外键的方式没有任何问题。证明这一点就是MySQL实际上阻止你插入违反你告诉它强制执行的外键的条目。问题是您尝试添加blood donor
条目而未指定与其相关的user
。您有两种选择:
donor_id
是外键,如果这是你想要的,它也可以是可空的,尽管你需要告诉Laravel / MySQL。以下是定义可空列的方法:
$table->unsignedInteger('donor_id')->nullable();
我冒昧地纠正你的拼写: blood donner&gt;献血者。正确的拼写也有助于编码可读性;)
如果您想要了解如何改进数据库设计以便充分利用外键,请按以下步骤操作:
第一件事:如果不是每个用户都是献血者,我只会有一个辅助blood_donors
表。如果100%的用户都是献血者,请不要过于复杂:只使用一个表并添加更多列。否则,请继续阅读。
我的users
表可能包含与一般个人信息相关的所有列:
之后,我可以通过users
“链接”blood_donors
表和foreign keys
表,这样我就不必重复了。我需要知道的是哪个用户对应哪个献血者,而我需要完成的只是一个id。这样,当我对数据库进行查询时,无论它是最初位于blood_donors
还是users
表,我都可以轻松地join
两个表一起并一次拥有所有数据,在两个不同的地方重复它。
所以,回到你的迁移,现在就足够了:
Schema::create('blooddonners', function(Blueprint $table)
{
$table->increments('id');
$table->unsignedInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade')->onUpdate('cascade');
$table->string('blood_group');
$table->date('last_date_of_donation');
$table->timestamps();
});
即。你不需要blood_donors
表中的“捐赠者姓名”,因为你已经将它记录在你的用户桌面上,毕竟他们是同一个人。您应该只有在献血背景下才有相关的列。
然后,您可以使用这样的查询访问所有这些数据(假设您已经设置了模型):
User::join('blood_donors', 'users.id', '=', 'blood_donors.user_id')->get();
你有一个同时包含两个表列的对象。请注意,具有完全相同名称的列将在最终对象中相互覆盖,因此如果要在该对象中可靠地访问ids
,则最好在select
部分指定别名的查询。如果必须,您甚至可以更改列名称。在Laravel你可以这样做:
User::select('users.*', 'users.name as donor_name', 'blood_donors.id as donor_id')
->join('blood_donors', 'users.id', '=', 'blood_donors.user_id')
->get();
查看Eloquent documentation on relationships,了解如何进一步完善数据库设计,并保持清晰,可读的代码。