Summary
- Context and Needs
- Minimal, Testable and Executable sources (with instructions for testing)
- Actual Results and Expected Results
- What I've tried
- The Question
Context and Needs
The relationship between both Eloquent models GalleryImage
and GalleryGroup
is: GalleryImage * <-> 1 GalleryGroup
. I want to save an instance of GalleryGroup
, then of GalleryImage
.
Minimal, Testable and Executable sources
Instructions to test
I wanted to show you how to test my code in the case you really want to do it ;-) . However, I think you don't actually need to test. Indeed, the code is very simple. By reading it, if you know more than me Laravel, maybe you will find the problem and be able to bring me some help. I let you reading the following contents but I think you'll agree with me.
Create the tables for GalleryGroup
and GalleryImage
(out of topic). The fields to create and the name of the tables are contained in the following sources.
Copy/Paste the Eloquent models and the script that instanciates them and tries to save them in DB.
Creates the routes of your choice to run the script and then, run the script (ie.: access the Web page or use a REST client)
The Eloquent models
-- GalleryGroup.php
<?php
namespace AppModels;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;
class GalleryGroup extends Model
{
use HasFactory;
protected $primaryKey = 'group_id';
private $name;
public function images() {
return $this->hasMany(GalleryImage::class);
}
}
-- GalleryImage.php
<?php
namespace AppModels;
use IlluminateDatabaseEloquentFactoriesHasFactory;
use IlluminateDatabaseEloquentModel;
class GalleryImage extends Model
{
use HasFactory;
protected $primaryKey = 'image_id';
public function group() {
return $this->hasOne(GalleryGroup::class, 'group_id', 'image_id');
}
}
Instanciations and concretization of the relationship
The Eloquent model GalleryGroup
is instanciated and saved in db; then, the Eloquent model GalleryImage
is instanciated and should be saved in 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();
Actual Results and Expected Results
The last line is never executed because this error is raised at the line $image->group()->save($img_group);
:
IlluminateDatabaseQueryException: 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
I don't understand why it tries to update the group entry, and I don't understand why group_id
is NULL
or empty, because $img_group
actually has a non-empty group_id
(cf.: the line var_dump($img_group->group_id);
).
The actual results are: 1) the model GalleryGroup
is correctly instanciated and correctly saved in db and 2) the model GalleryImage
is correctly instanciated and not saved in db because of the above SQL error is raised.
The expected results are: 1) the model GalleryGroup
is correctly instanciated and correctly saved in db and 2) the model GalleryImage
is correctly instanciated and saved in db.
What I've tried
I've tried to var_dump
several times several variables but did not found any relevant information to help debugging this issue.
I've read and re-read the docs https://laravel.com/docs/8.x/eloquent-relationships#the-save-method and https://laravel.com/docs/8.x/eloquent#primary-keys but did not found any relevant information to help debugging this issue.
The Question
Why is this error raised and how to fix it?
question from:
https://stackoverflow.com/questions/65641623/laravel-saving-a-relationship-when-instanciating-an-eloquent-model-rises-this-s 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…