具有外键约束的 Laravel 模型关系
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26205636/
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 Model relations with foreign key constraints
提问by Matthijn
I'm trying to get foreign key constraints to work in Laravel. But I can't seem to save my models anymore.
我试图让外键约束在 Laravel 中工作。但我似乎无法再保存我的模型了。
My database structure is setup as follows (I've removed unnecessary code):
我的数据库结构设置如下(我删除了不必要的代码):
Schema::create($this->tableName, function(Blueprint $table)
{
$table->increments('id');
$table->string('username')->unique();
$table->string('password', 64);
$table->integer('address_id')->unsigned();
});
Schema::create($this->tableName, function(Blueprint $table)
{
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('name');
$table->string('surname');
$table->string('street');
$table->string('number');
$table->string('town');
$table->string('country');
});
So the Addressis in a separate table and an Addressbelongs to a User. The Userhas an Address.
所以 the Addressis 在一个单独的表中,而 anAddress属于 a User。该User有Address。
Next I've created the corresponding models:
接下来我创建了相应的模型:
Class User extends Model
{
public function address()
{
return $this->hasOne('Address');
}
}
Class Address extends Model
{
public function user()
{
return $this->belongsTo('User');
}
}
Now when I try to create a Userwith an Addressand save it I get constraint errors. I've tried it both ways (saving the Userfirst and saving the Addressfirst) but both give an error.
现在,当我尝试User使用 an创建一个Address并保存它时,我收到约束错误。我已经尝试了两种方式(保存第User一个和保存第Address一个),但都给出了错误。
The first idea I had was this:
我的第一个想法是这样的:
// Create a new user
$user = new User($data);
$address = new Address($addressData);
$address->user()->associate($user);
$user->push(); // Error here
But this gives the error:
但这给出了错误:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`eet`.`users`, CONSTRAINT `users_address_id_foreign` FOREIGN KEY (`address_id`) REFERENCES `addresses` (`id`)) (SQL: insert into `users` (`username`, `email`, `password`, `type`, `phone`, `cellphone`, `newsletter_week`, `ip`, `updated_at`, `created_at`) values (adsadsad, [email protected], passWO23dw00, customer, 123123213, 1234567890, 1, ::1, 2014-10-05 19:56:03, 2014-10-05 19:56:03))
So I tried saving the Addressfirst, and then the Userlike:
所以我尝试保存第Address一个,然后User像:
$user = new User($data);
$address = new Address($addressData);
$address->save(); // Error here
$address->user()->associate($user);
$user->push();
But then the following error is generated:
但是随后会生成以下错误:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'user_id' cannot be null (SQL: insert into `addresses` (`name`, `surname`, `street`, `number`, `town`, `country`, `user_id`) values (Foo, Bar, FooStreet, 200, Townsville, nl, ))
So what is a good way to do this? I could make the field address_idfor the Usernullable, but is that a good practise? I want a Userto always have an Address.
那么有什么好的方法可以做到这一点呢?我可以address_id为User可空字段创建字段,但这是一个好习惯吗?我想要一个User总是有一个Address.
回答by Marcin Nabia?ek
I would start with database design first.
我会先从数据库设计开始。
For userstable I would use:
对于users表,我会使用:
$table->increments('id');
$table->string('username')->unique();
$table->string('password', 64);
address_id is not necessary here.
address_id 在这里不是必需的。
For addressestable I would use:
对于addresses表,我会使用:
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->string('name');
$table->string('surname');
$table->string('street');
$table->string('number');
$table->string('town');
$table->string('country');
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('CASCADE');
You should use foreign key in addresses table and add onDelete('CASCADE`) - now if you remove user, address will be removed automatically. You won't have any orphaned addresses.
您应该在地址表中使用外键并添加 onDelete('CASCADE`) - 现在如果您删除用户,地址将自动删除。您不会有任何孤立的地址。
Now inserting data:
现在插入数据:
$user = new User($data);
$user->save();
$address = new Address($addressData);
$user->address()->save($address);
You don't need to put in $addressDataany user_id- it will be filled automatically.
您无需输入$addressData任何内容user_id- 它将自动填充。
回答by The Alpha
At first save the parent modeland in this case it's Userso:
首先保存父级model,在这种情况下是User这样的:
$user = new User($data);
$user->save();
Then try:
然后尝试:
// $addressData ...
$addressData['user_id'] = $user->id;
$address = new Address($addressData);
$address->save();
Or maybe:
或者可能:
$user = new User($data);
$user->address = new Address($addressData);
$user->push();

