Laravel: Saving a relationship when instanciating an Eloquent model rises this SQL error: "Integrity constraint violation"
Laravel: Saving a relationship when instanciating an Eloquent model rises this SQL error: "Integrity constraint violation"
总结
- 背景和需求
- 最小的、可测试的和可执行的源代码(带有测试说明)
- 实际结果和预期结果
- 我试过的
- 问题
背景和需求
Eloquent 模型 GalleryImage
和 GalleryGroup
之间的关系是:GalleryImage * <-> 1 GalleryGroup
。我想保存 GalleryGroup
的实例,然后保存 GalleryImage
.
的实例
最小的、可测试的和可执行的源代码
测试说明
我想向您展示如何在您确实想要测试我的代码的情况下测试它;-)。但是,我认为您实际上不需要测试。确实,代码非常简单。通过阅读它,如果你比我更了解Laravel,也许你会发现问题并能给我带来一些帮助。我让你阅读以下内容,但我想你会同意我的看法。
为 GalleryGroup
和 GalleryImage
创建表(题外话)。要创建的字段和表的名称包含在以下来源中。
Copy/Paste Eloquent 模型和实例化它们并尝试将它们保存在数据库中的脚本。
创建您选择的路由到 运行 脚本,然后 运行 脚本(即: 访问网页或使用 REST 客户端)
Eloquent 位模特
-- GalleryGroup.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class GalleryGroup extends Model
{
use HasFactory;
protected $primaryKey = 'group_id';
private $name;
public function images() {
return $this->hasMany(GalleryImage::class);
}
}
-- GalleryImage.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class GalleryImage extends Model
{
use HasFactory;
protected $primaryKey = 'image_id';
public function group() {
return $this->hasOne(GalleryGroup::class, 'group_id', 'image_id');
}
}
关系的实例化和具体化
Eloquent模型GalleryGroup
被实例化并保存在db中;然后,Eloquent 模型 GalleryImage
被实例化并且应该保存在 db:
$img_group = new GalleryGroup();
$img_group->name = 'foobar';
$img_group->save();
$image = new GalleryImage();
var_dump($img_group->group_id); // It exists and it's not empty
$image->group()->save($img_group);
$image->save();
实际结果和预期结果
最后一行永远不会执行,因为在 $image->group()->save($img_group);
:
行出现了这个错误
Illuminate\Database\QueryException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'group_id' cannot be null (SQL: update gallery_groups
set group_id
= ?, gallery_groups
.updated_at
= 2021-01-09 10:16:44 where group_id
= 24) in file /var/www/html/api/vendor/laravel/framework/src/Illuminate/Database/Connection.php on line 671
我不明白为什么它会尝试更新组条目,我也不明白为什么 group_id
是 NULL
或空的,因为 $img_group
实际上有一个非-空group_id
(cf.:行var_dump($img_group->group_id);
)。
实际结果是:1) 模型 GalleryGroup
被正确实例化并正确保存在数据库中 2) 模型 GalleryImage
被正确实例化并且没有保存在数据库中,因为上述 SQL 出现错误。
预期结果是:1) 模型 GalleryGroup
正确实例化并正确保存在数据库中,2) 模型 GalleryImage
正确实例化并保存在数据库中。
我试过的
我已经尝试 var_dump
几次几个变量,但没有找到任何相关信息来帮助调试这个问题。
我已经阅读并重新阅读文档 https://laravel.com/docs/8.x/eloquent-relationships#the-save-method and https://laravel.com/docs/8.x/eloquent#primary-keys,但没有找到任何相关信息来帮助调试此问题。
问题
为什么会出现此错误以及如何解决?
其中一个关系必须是 belongsTo
,因为其中一个 table 具有与另一个 table 相关的外键。我假设 GalleryImage 属于 GalleryGroup:
GalleryGroup
images
hasMany GalleryImage
GalleryImage
gallery
belongsTo GalleryGroup
一旦这些设置正确,您应该能够执行此操作以保存关系:
$img_group->images()->save($image);
总结
- 背景和需求
- 最小的、可测试的和可执行的源代码(带有测试说明)
- 实际结果和预期结果
- 我试过的
- 问题
背景和需求
Eloquent 模型 GalleryImage
和 GalleryGroup
之间的关系是:GalleryImage * <-> 1 GalleryGroup
。我想保存 GalleryGroup
的实例,然后保存 GalleryImage
.
最小的、可测试的和可执行的源代码
测试说明
我想向您展示如何在您确实想要测试我的代码的情况下测试它;-)。但是,我认为您实际上不需要测试。确实,代码非常简单。通过阅读它,如果你比我更了解Laravel,也许你会发现问题并能给我带来一些帮助。我让你阅读以下内容,但我想你会同意我的看法。
为
GalleryGroup
和GalleryImage
创建表(题外话)。要创建的字段和表的名称包含在以下来源中。Copy/Paste Eloquent 模型和实例化它们并尝试将它们保存在数据库中的脚本。
创建您选择的路由到 运行 脚本,然后 运行 脚本(即: 访问网页或使用 REST 客户端)
Eloquent 位模特
-- GalleryGroup.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class GalleryGroup extends Model
{
use HasFactory;
protected $primaryKey = 'group_id';
private $name;
public function images() {
return $this->hasMany(GalleryImage::class);
}
}
-- GalleryImage.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class GalleryImage extends Model
{
use HasFactory;
protected $primaryKey = 'image_id';
public function group() {
return $this->hasOne(GalleryGroup::class, 'group_id', 'image_id');
}
}
关系的实例化和具体化
Eloquent模型GalleryGroup
被实例化并保存在db中;然后,Eloquent 模型 GalleryImage
被实例化并且应该保存在 db:
$img_group = new GalleryGroup();
$img_group->name = 'foobar';
$img_group->save();
$image = new GalleryImage();
var_dump($img_group->group_id); // It exists and it's not empty
$image->group()->save($img_group);
$image->save();
实际结果和预期结果
最后一行永远不会执行,因为在 $image->group()->save($img_group);
:
Illuminate\Database\QueryException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'group_id' cannot be null (SQL: update
gallery_groups
setgroup_id
= ?,gallery_groups
.updated_at
= 2021-01-09 10:16:44 wheregroup_id
= 24) in file /var/www/html/api/vendor/laravel/framework/src/Illuminate/Database/Connection.php on line 671
我不明白为什么它会尝试更新组条目,我也不明白为什么 group_id
是 NULL
或空的,因为 $img_group
实际上有一个非-空group_id
(cf.:行var_dump($img_group->group_id);
)。
实际结果是:1) 模型 GalleryGroup
被正确实例化并正确保存在数据库中 2) 模型 GalleryImage
被正确实例化并且没有保存在数据库中,因为上述 SQL 出现错误。
预期结果是:1) 模型 GalleryGroup
正确实例化并正确保存在数据库中,2) 模型 GalleryImage
正确实例化并保存在数据库中。
我试过的
我已经尝试 var_dump
几次几个变量,但没有找到任何相关信息来帮助调试这个问题。
我已经阅读并重新阅读文档 https://laravel.com/docs/8.x/eloquent-relationships#the-save-method and https://laravel.com/docs/8.x/eloquent#primary-keys,但没有找到任何相关信息来帮助调试此问题。
问题
为什么会出现此错误以及如何解决?
其中一个关系必须是 belongsTo
,因为其中一个 table 具有与另一个 table 相关的外键。我假设 GalleryImage 属于 GalleryGroup:
GalleryGroup
images
hasMany GalleryImage
GalleryImage
gallery
belongsTo GalleryGroup
一旦这些设置正确,您应该能够执行此操作以保存关系:
$img_group->images()->save($image);