具有外键约束的 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 10:14:49  来源:igfitidea点击:

Laravel Model relations with foreign key constraints

phpmysqllaravelconstraintsrelation

提问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。该UserAddress

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_idUser可空字段创建字段,但这是一个好习惯吗?我想要一个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();