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

viper75x's avatar

SQLSTATE Cannot insert null values...

L8, with Blade

    {
        // InvMaterial::create($this->validateInvMaterial());
        // dd(request()->all());
        
        $item = new InvMaterial($this->validateInvMaterial());
        $item->category_id = 2;
        $item->classification_id = 4;
        $item->save();
        return redirect(route('items.index'));
    }

I set the category and classification as those were the first null value errors I received. Then it kept going.

the dd returns:

array:7 [▼
  "_token" => "DBMp5l2tSCEEzidnIOJdf5Hgw3IhVN5rnpE6A7Fy"
  "catalogNumber" => "123456"
  "description" => "asdf"
  "short" => "asdkjf"
  "classification" => "2"
  "category" => "4"
  "stocked" => "1"
]

so, nothing is null. The current null error is on the catalogNumber.

All six fields are fillable. As you can see, there are two FKs, category_id and classification_id.

The 'short' field is the only nullable.

There are three other boolean fields in the table, not included in the form, that are NOT nullable, but the default, via the migration, is set to true or false...hm, I'm wondering if this might cause a problem?

Thoughts?

Also, I could use some tips on formatting my posts, as I see most everyone else has these nice colored code wrappers... Hmm, I moved those backquotes? around and got a better looking post

Update: I've added the other fields and set their values in the store function as well, but the error remains.

Below is the code specific to this field.

<div class="field col-sm-8">
                <label class="label" for="catalogNumber">Catalog Number</label>
                <div class="control">
                    <input type="text" class="input form-control @error('catalogNumber')" name="catalogNumber" id="catalogNumber" value="">
                    @error('catalogNumber')
                        <p class="help is-warning">{{ $errors->first('catalogNumber') }}</p>
                    @enderror
                </div>
            </div>
0 likes
11 replies
MarianoMoreyra's avatar

Hi @viper75x

Please share the code of $this->validateInvMaterial()

Also, what do you get if you do a

dd($item);

right before the $item->save()?

Tray2's avatar

This is most likely the issue.

"catalogNumber" => "123456"

it should be

"catalog_number" => "123456"

When naming fields in the database the words are seperated with an underscore.

Make sure the name of the field in your migration is catalog_number and that you have made the change in your form, validation and store method.

viper75x's avatar

@marianomoreyra

public function validateInvMaterial()
    {
        //need to generate a new unique catalog number
        return request()->validate([
            'description' => 'required',
            'catalogNumber' => 'required',
            'category' => 'required',
            'short' => 'required',
            'classification' => 'required'
        ]);
    }

DD $item:

App\Models\InvMaterial {#390 ▼
  #connection: "sqlsrv"
  #table: "inv_Materials"
  #fillable: array:11 [▼
    0 => "description"
    1 => "short"
    2 => "catalogeNumber"
    3 => "stocked"
    4 => "classification_id"
    5 => "category_id"
    6 => "discontinued"
    7 => "review"
    8 => "inUse"
    9 => "disc_date"
    10 => "reason"
  ]
  #primaryKey: "id"
  #keyType: "int"
  +incrementing: true
  #with: []
  #withCount: []
  #perPage: 15
  +exists: false
  +wasRecentlyCreated: false
  #attributes: array:8 [▼
    "description" => "asdfsda"
    "short" => "asdf"
    "category_id" => 2
    "disc_date" => null
    "reason" => null
    "discontinued" => false
    "inUse" => true
    "classification_id" => 4
  ]
  #original: []
  #changes: []
  #casts: []
  #classCastCache: []
  #dates: []
  #dateFormat: null
  #appends: []
  #dispatchesEvents: []
  #observables: []
  #relations: []
  #touches: []
  +timestamps: true
  #hidden: []
  #visible: []
  #guarded: array:1 [▼
    0 => "*"
  ]
}

@tray2 Well, that wasn't it. Coming from Visual Basic, I tend not to use underscores in my field names, it doesn't look right, lol. However, I took a closer look at the name of that particular field, and I had misspelled it in one place...the fillable section.

After fixing that, I was able to create a new record. However, the category and classification is not being picked up from the form, which presented another null value error.

Question: What attribute does Laravel look for to determine which field a value belongs to: input name or id?

Since I wasn't sure, I changed the label 'for' attr. and the input control name and id attr. all to the field name. For some reason this did not work, so I stopped the local server, dumped the autoload, and tried again. This time, when I DD, I got the category_id and classification_id values passed through.

Something I wasn't aware of, either 1) needing to restart the server; or 2) dumping autoload files after making changes to the HTML elements' attributes.

After more testing, it appears that the form looks at the name attribute of the control, and restarting the server is what is needed.

Tray2's avatar

The naming convention for field names is catalog_number, I agree that it looks a bit of when you use camelcase in you variable and method names but it's there for a reason. SQL doesn't really care about the case so ´catalogNumberandcatalognumber` is the same thing most of the time. In some databases there is a difference when you create a table depending on if you use quotes or not which can lead to strange issues later on. So stick with lowercase letters and seperate the words with an underscore to avoid later headaches.

In your form you put a name to the input

<input type="text" name="title">

That name becomes the property used to access the value sent to the server.

You can access it like this

$request->title

Everything should be validated so you can do this

$validData = $request->validate(['title' => 'required']);

Then you need to create the record in the database which you can do like this

Model::create($validData);

The validation can be inlined like this

Model::create($request->validate(['title' => 'required']));

There are more than one way to do the above but that is one way to do it.

You need to allow for massassignment in your model and there are several ways to do that but since you are a good programmer and validate everything you can get away with

protected $guarded = [];

Which means you can assign all fields in the table.

viper75x's avatar

Here is what I currently have:

public function store(Request $request)
    {
	$item = new InvMaterial($this->validateInvMaterial());

   	$item->save();
        return redirect(route('items.index'));
    }

The validation function with the required fields I posted earlier, which I'll include here as well.

public function validateInvMaterial()
    {
        //need to generate a new unique catalog number
        return request()->validate([
            'description' => 'required',
            'catalogNumber' => 'required',
            'category_id' => 'required',
            'short' => 'required',
            'classification_id' => 'required'
        ]);
    }

Would there be any added value to using a variable such as you described?

$validateData = $this->validateInvMaterial();

Then, by using

protected $guarded = [];

I would not need the $fillable array.

viper75x's avatar

Follow up: for the table fields that have defaults of null, do I need to include those somehow in the create form, or controller?

MarianoMoreyra's avatar

@viper75x you're right, it's the name attribute that gets sent for each form control.

Regarding the server restart, that shouldn't be needed at all after a simple html modification! Probably your page got cached I guess...

Finally, you don't need to include those fields that have defaults (not sure what you mean by 'defaults of null' but I'm assuming that you are talking about default values, different from null, defined at your migrations for not nullable fields).

viper75x's avatar

Some of the fields I did set the default to null in the migrations and some are set to either false or true.

It looks like the page was indeed cached. I did not take that into account, which I discovered a few moments later with a bit more testing.

I wasn't sure if the name or id attribute of the HTML element was referenced in the request.

Snapey's avatar
Snapey
Best Answer
Level 122

Your $fillable array contains a typo catalogeNumber

and the model attributes does not contain anything resembling catalogueNumber (or catalogNumber)

#attributes: array:8 [▼
    "description" => "asdfsda"
    "short" => "asdf"
    "category_id" => 2
    "disc_date" => null
    "reason" => null
    "discontinued" => false
    "inUse" => true
    "classification_id" => 4
  ]
viper75x's avatar

Thanks Snapey, I caught that earlier and cleared that one problem right up!

Snapey's avatar

I identified two problems there?

1 like

Please or to participate in this conversation.