具有外键约束的 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 Address
is in a separate table and an Address
belongs to a User
. The User
has an Address
.
所以 the Address
is 在一个单独的表中,而 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 User
with an Address
and save it I get constraint errors. I've tried it both ways (saving the User
first and saving the Address
first) 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 Address
first, and then the User
like:
所以我尝试保存第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_id
for the User
nullable, but is that a good practise? I want a User
to always have an Address
.
那么有什么好的方法可以做到这一点呢?我可以address_id
为User
可空字段创建字段,但这是一个好习惯吗?我想要一个User
总是有一个Address
.
回答by Marcin Nabia?ek
I would start with database design first.
我会先从数据库设计开始。
For users
table I would use:
对于users
表,我会使用:
$table->increments('id');
$table->string('username')->unique();
$table->string('password', 64);
address_id is not necessary here.
address_id 在这里不是必需的。
For addresses
table 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 $addressData
any user_id
- it will be filled automatically.
您无需输入$addressData
任何内容user_id
- 它将自动填充。
回答by The Alpha
At first save the parent model
and in this case it's User
so:
首先保存父级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();