Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

plenty's avatar

[SOLVED] Integrity constraint violation: 1452 - "Learning Laravel's Eloquent"

I have the book, 'Learning Laravel's Eloquent', & believe I've followed its instruction to the letter, but I have ground to a halt at this error message. I'm very new to all this, I feel I've read everything related to this error and yet here I am, appealing to you fine folks. I can't be the only one who's faltered at this juncture while trying to follow this book, so I put this out there on behalf of us all!

Here is the full error message:

QueryException in Connection.php line 655:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`eloquent_journey`.`books`, CONSTRAINT `books_author_id_foreign` FOREIGN KEY (`author_id`) REFERENCES `authors` (`id`)) (SQL: insert into `books` (`title`, `pages_count`, `price`, `description`, `updated_at`, `created_at`) values (My First Book!, 230, 10.5, A very original lorem ipsum dolor sit amet..., 2016-04-14 13:54:53, 2016-04-14 13:54:53))

I should say that I'm stuck at the point where I have just created my first model, & am trying to add 'My First Book' via the routes.php file.

Here is my routes file;

use Illuminate\Database\Schema\Blueprint;

Route::get('create_books_table', function() {
    Schema::create('books', function(Blueprint $table)
    {
        $table->increments('id');
        $table->string('title', 30);
        $table->integer('pages_count');
        $table->decimal('price', 5, 2);
        $table->text('description');
        $table->timestamps();
    });
});

Route::get('update_books_table', function() {
    Schema::table('books', function(Blueprint $table)
    {
        $table->string('title', 250)->change();
    });
});
    
Route::get('update_books_table_2', function() {
    //creating authors table p33...
    Schema::create('authors', function(Blueprint $table)
    {
        $table->increments('id');
        
        $table->string('first_name');
        $table->string('last_name');
        
        $table->timestamps();
    });
    
    Schema::table('books', function(Blueprint $table)
    {
        //creating the index on the title column p33...
        $table->index('title');
        
        //creating the foreign key ...
        $table->integer('author_id')->unsigned();
        $table->foreign('author_id')->references('id')->on('authors');
    });
});

Route::get('book_create', function() {
    $book = new \App\Book;
    
    $book->title = 'My First Book!';
    $book->pages_count = 230;
    $book->price = 10.5;
    $book->description = 'A very original lorem ipsum dolor sit amet...';
    
    $book->save();
});

Here is a pair of migrations that are part of the project:

<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class PublishersUpdate extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('publishers', function(Blueprint $table)
        {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        });
        
        Schema::table('books', function(Blueprint $table)
        {
            $table->integer('publisher_id')->unsigned();
            $table->foreign('publisher_id')->references('id')->on('publishers');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('books', function(Blueprint $table)
        {
            $table->dropForeign('books_publisher_id_foreign');
            $table->dropColumn('publisher_id');
        });
        
        Schema::drop('publishers');
    }
}
<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class TagsUpdate extends Migration
{
    public function up()
    {
        Schema::create('tags', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->timestamps();
        });
        
        Schema::create('book_tag', function(Blueprint $table) {
            $table->increments('id');
            
            $table->integer('book_id')->unsigned();
            $table->integer('tag_id')->unsigned();
            
            $table->foreign('book_id')->references('id')->on('books');
            $table->foreign('tag_id')->references('id')->on('tags');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('book_tag');
        Schema::drop('tags');
    }
}

Finally, here is the 'Book' model - the protected $fillable line is the only deviation from what is stated in the book - it was my attempt to solve this dilemma based on stuff I'd read elsewhere:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Book extends Model {
    
    protected $fillable = ['id', 'author_id', 'title', 'pages_count', 'price', 'description', 'updated_at', 'created_at'];
}

Thanks in advance for any & every scrap of help you offer me - I'd really like to kick on & move through this book & hopefully one day create wonderful things with Laravel!

0 likes
7 replies
tykus's avatar

The error means that you are not providing the required author_id to the INSERT INTO books ... statement. Presumably, you are hitting the book_create route after theupdate_books_table_2 route. As you can see there is no author_id being set, which is leading to the error:

Route::get('book_create', function() {
    $book = new \App\Book;
    
    $book->title = 'My First Book!';
    $book->pages_count = 230;
    $book->price = 10.5;
    $book->description = 'A very original lorem ipsum dolor sit amet...';
    
    $book->save();
});

For what it's worth

I don't know this book, but would be wary of any tutorial that would have migrations in the routes file - yes, it will work; in fact, if you were crazy enough, you could write the entire application inside the routes file; but, it is an an abuse of routing and migrations in a single step.

plenty's avatar

Thanks so much for your response!

The author does allude to the fact that it is bad practice to use the routes file in this way, but presumably it's written like this as the focus is on eloquent, & not Laravel as a whole. Just a guess, however. I am rapidly losing faith in this author, however - this has tied me up in knots for the best part of a day now! I am wondering now whether this stuff is too complex for my skill level right now - I've added an author_id field as you prescribed, but it has made no difference. Incidently, you're right to assume that those routes have been hit in the order that they appear.

Route::get('book_create', function() {
    $book = new \App\Book;
    
    $book->title = 'My First Book!';
    $book->pages_count = 230;
    $book->price = 10.5;
    $book->description = 'A very original lorem ipsum dolor sit amet...';
    $book->author_id = 12345; 

    $book->save();
});

Is that what you meant?

1 like
tykus's avatar

Is there an author with id = 12345, probably not? If you do not have an author in the authors table already (I don't see where one might have been created from what you have posted) then you can create one first -- forgive me for using routes file despite what I said earlier ;D

Route::get('author_create', function() {
    $author = App\Author::create([    
        'first_name' => 'Cookie',
        'last_name' => 'Monster'
    ]);

    return $author;
});

This will return a JSON representation of the newly created author object - note the id, and use this in the book_create route instead of 12345

tykus's avatar

The real magic happens whenever you begin creating relationships between your Book and Author classes (a Book belongs to an Author; an Author has many Books). You will then be able to set the foreign key (author_id) on the book object through the relationship.

The Laravel From Scratch series here is free; episode 7 deals with Eloquent. It a great resource whenever you are starting out; so too are these forums!

plenty's avatar

I appreciate that you have violated your ethics to bring me a solution via the routes.php - I bet that stings a little, huh?

I must be very tired, & my irritation is clouding my judgement - but still, I have an Integrity constraint violation :(

I am happily creating authors with your author_create route, from which I get additions to my authors table & output like this:

{"first_name":"Cookie","last_name":"Monster","updated_at":"2016-04-14 16:59:33","created_at":"2016-04-14 16:59:33","id":2}

I have an Author model which looks like this;

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Author extends Model
{
    protected $fillable = ['id', 'author_id', 'title', 'pages_count', 'price', 'description', 'updated_at', 'created_at', 'first_name', 'last_name'];
}

My book_create route now has a valid author_id.

Route::get('book_create', function() {
    $book = new \App\Book;
    
    $book->title = 'My First Book!';
    $book->pages_count = 230;
    $book->price = 10.5;
    $book->description = 'A very original lorem ipsum dolor sit amet...';
    $book->author_id = 2;
    
    $book->save();
    
    echo 'Book: ' . $book->id;
});

All this, & the result is all too familiar:

SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`eloquent_journey`.`books`, CONSTRAINT `books_publisher_id_foreign` FOREIGN KEY (`publisher_id`) REFERENCES `publishers` (`id`)) (SQL: insert into `books` (`title`, `pages_count`, `price`, `description`, `author_id`, `updated_at`, `created_at`) values (My First Book!, 230, 10.5, A very original lorem ipsum dolor sit amet..., 2, 2016-04-14 17:10:38, 2016-04-14 17:10:38))

I have got plenty of value from laracasts & that series, 'Laravel from Scratch' - but by purchasing this book, I was hoping for a deeper dive into eloquent, as I want to use a package called Goutte to scrape information from other websites, stick it in my databases for me to manipulate & throw up on my own site. This author has missed a significant chunk out of his own book, & it looks like I'm going to abandon it & seek my answers elsewhere - but I would just like to see this part through to justify the time I've spent spinning my wheels.

As ever, I very much appreciate the time you have taken to help me out!

tykus's avatar

This is progress (in the form of a new problem :D); it is relating to the publishers foreign key constraint - the relevant part of the error message...FOREIGN KEY ('publisher_id') REFERENCES 'publishers' ('id')...

So, one of the proper migrations you created make a modification to your books table:

Schema::table('books', function(Blueprint $table)
{
    $table->integer('publisher_id')->unsigned();
    $table->foreign('publisher_id')->references('id')->on('publishers');
});

So now, you will also need to make sure you have a publisher_id property set on your Book object before you try to save it. The approach is the very same as I gave you earlier for the Author, i.e. create a Publisher and set the returned id as the $book->publisher_id.

This is kind of how Test-Driven Development works, albeit without the tests in this case :D - you deal with the current failure and when that is fixed move onto the next one, and so on until it does what you specify.

Keep at it; practice makes perfect (just realise that perfect is impossible*).

plenty's avatar

Well, well .. and that's finally that! Really appreciate the help, @tykus_ikus - I now have A book in my table - Woo-Hooo!!! More importantly, I feel more equipped to decode that error message, & tie up the loose ends that it is complaining about.

I will persist a little further with this book - but for anyone reading this - I'd advise against this book as a resource.

Thanks once again!

Please or to participate in this conversation.