4

Using Laravel 5.8.31 I seem to be getting an integrity constraint violation for something in a table that should not be null. The issue is that its telling me posts.title in my migration file should not be null, but that variable is not even in the migration table.

SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint >failed: posts.title (SQL: insert into "posts" ("caption", "image", "user_id", >"updated_at", "created_at") values (kjhgj, C:\xampp\tmp\phpE3B7.tmp, 1, 2019->08-14 07:14:03, 2019-08-14 07:14:03))

I am trying to learn Laravel and have been following this youtube tutorial https://www.youtube.com/watch?v=ImtZ5yENzgE

From the error page that I get from my browser I can see that the error is thrown in PostsController.php.

I made it to time 2:04:00 but ran into this issue. I have read many other questions asked and answered here, but with no luck.

Posts Migration File

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedBigInteger('user_id');
            $table->string('caption');
            $table->string('image');
            $table->timestamps();
            $table->index('user_id');
            // THERE IS NO 'title' entry.
        });
    }

Posts Model File

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //Tutorial uses guarded rather than fillable
    protected $guarded = [];

    public function user(){
    return $this->belongsTo(User::class);
    }
}

Posts Controller File

class PostsController extends Controller
{
    public function create()
    {
        return view('posts.create');
    }

    public function store()
    {
        $data = request()->validate([
            'caption' => 'required',
            'image' => ['required','image'],
        ]);

       auth()->user()->posts()->create($data); //ERROR IS THROWN HERE


        dd(request()->all());
    }
}

I have a page where the user enters a caption and uploads file. Without any validation I can dd(request()->all()); to see that the caption and the file were received. But when I add the validation and the auth() line in the controller file I get the integrity constraint violation for "posts.title"

I expect the caption and the image to be added to the database.

First time posting because I can usually find the answer, but this time I'm stuck.

Edit: here is the error: Error Image

Solved

@Vipertecpro was able to solve my issue. I had to run the following two commands: php artisan migrate:refresh --seed then php artisan optimize:clear.

@Don'tPanic Explained why the commands worked in the comments of this post.

WhatAmIDoing
  • 85
  • 1
  • 6
  • Try this `Post::create(['column_name' => $request->get('value')])`, instead of `auth()->user()->posts()->create($data);` and why don't you have all columns in $fillable variable inside of model ? – Vipertecpro Aug 14 '19 at 08:08
  • Please share the video link which you're following to implement this simple crud – Vipertecpro Aug 14 '19 at 08:16
  • @Vipertecpro I have the link in the post along with the time in the video. The reason I'm not using fillable is because he said to simply pass an empty string to $guarded (doesnt seem like a good idea, but im just now learning). – WhatAmIDoing Aug 14 '19 at 08:19
  • Refer this to get clear understanding https://laravel.com/docs/5.8/eloquent#inserting-and-updating-models and please consider watching any video for programming very last way of learning anything otherwise two very effective methods are official documents and hit & trial method, believe me you will find more than 2 ways to insert data into database. :) Happy coding. – Vipertecpro Aug 14 '19 at 08:30
  • "title" column is there in your post table or not? – sandip bharadva Aug 14 '19 at 08:40
  • @sandy "title" is not in my post table – WhatAmIDoing Aug 14 '19 at 08:45
  • Run this `php artisan migrate:refresh --seed`, then this `php artisan optimize:clear`, and then try – Vipertecpro Aug 14 '19 at 08:46
  • @Vipertecpro that did it! Thank you! – WhatAmIDoing Aug 14 '19 at 08:53
  • Always happy to help. :) – Vipertecpro Aug 14 '19 at 08:54
  • Can you check the DB directly and confirm there is really no `title` field? – Don't Panic Aug 14 '19 at 08:58
  • @Don'tPanic not sure how to check directly (video is using sqlite), but the Posts schema does not have a title entry and when I use tinker to get the post there is no title entry either. – WhatAmIDoing Aug 14 '19 at 09:15
  • @WhatAmIDoing the solution you posted shows that your table really **did** have a `title` field. To explain what the commands you used actually do: [`migrate refresh`](https://laravel.com/docs/5.8/migrations#running-migrations) will first delete your tables, and then recreate them from scratch. If that fixed the problem, it means your table previously really did have a `title` field. Maybe you once experimented with Wordpress, which also has a `posts` table and it has a title field. If you re-used the same DB for this tutorial, maybe that table was still there. – Don't Panic Aug 14 '19 at 09:21
  • @Don'tPanic Ohh, that makes a lot of sense. I appreciate you taking the time to explain it to me. – WhatAmIDoing Aug 14 '19 at 09:28

2 Answers2

1

To permit to Laravel to do a massive insert or update in the database, you must declare the $fillable variable in the model.

In your case:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //Tutorial uses guarded rather than fillable
    //protected $guarded = []; // If you use $fillable do not use $guarded

    // HERE
    protected $fillable = ['user_id', 'caption', 'image'];  

    public function user(){
        return $this->belongsTo(User::class);
    }
}

If you do not do that, Laravel try to insert ALL data of the array in the DB table.

Giacomo M
  • 4,450
  • 7
  • 28
  • 57
  • I understand that but the video passes an empty string to guarded instead. Even if I add your line to my code and comment out the guarded line in the Post Model I still get the error for posts.title, which does not make sense to me. – WhatAmIDoing Aug 14 '19 at 08:14
  • guarded is the opposite of the fillable. You use it to say to laravel which fields are NOT to filled before doing massive insert or update. I edited my answer – Giacomo M Aug 14 '19 at 08:49
  • Oh I see. That's why the videos says to pass an empty array to it. It stops him from having to make a fillable every time. Anyways thank you for the replies. @Vipertecpro solved my issue. I had to run two commands. – WhatAmIDoing Aug 14 '19 at 08:56
0

This is a long shot but I would have done things differently and tested everything manually to see if it works. For an example, you could try this:

class PostsController extends Controller
{
    public function create()
    {
        return view('posts.create');
    }

    public function store(Request $request)
    {

        //Remove this for now
        //$data = request()->validate([
        //    'caption' => 'required',
        //    'image' => ['required','image'],
        //]);

       $post = new Post;

       $post->user_id = Auth::user()->id;

       $post->caption = $request->caption;
       //This assumes that you have 'caption' as your `name` in html. '<input type="text" name="caption" />'

       $post->image = $request->image;
       //The image should be processed but this will give an output for now.

       $post->save();

       //The save ignores $fillable or any such and depends on the request and SAVES it to the model or table


        return 'worked!';
    }
}

Let me know if this works.

Mohamed Ahmed
  • 195
  • 1
  • 3
  • 16