Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
136 views
in Technique[技术] by (71.8m points)

Laravel: Saving a relationship when instanciating an Eloquent model rises this SQL error: "Integrity constraint violation"

Summary

  1. Context and Needs
  2. Minimal, Testable and Executable sources (with instructions for testing)
  3. Actual Results and Expected Results
  4. What I've tried
  5. 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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

One of these relationships needs to be a belongsTo as one of these tables has the foreign key on it that relates to the other table. I would assume a GalleryImage belongs to a GalleryGroup:

GalleryGroup
    images
        hasMany GalleryImage

GalleryImage
    gallery
        belongsTo GalleryGroup

Once those are setup correctly you should be able to do this to save the relationship:

$img_group->images()->save($image);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...