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

warpig's avatar
Level 12

Field 'category_id' doesn't have a default value

Did I just forget how to add new columns into my Controller? I know iv'e done this a few times, I just can't see the error right away, I need some pointers, please... I will briefly go through what I did:

  1. Added a migration, "create_categories_table" with the foreign key statements, etc
  2. Included the relationship between the "Post" and "Category" model
  3. In my "create" view form, I added the foreach loop and gave it the name: "categories[]"
  4. On the controller it's added inside the query request, on the create method, and since I have a validate variable I added the name once again in that one as well.

Store method, chained query request:

        $post = new Post(request(['title', 'body', 'slug', 'image_url', 'categories']));

Create method:

    public function create()
    {   
        return view('posts.create', [
            'tags' => Tag::all(),
            'categories' => Category::all()
        ]);
    }

Validate method:

    protected function validatePost() 
    {
        return request()->validate([
            'title' => 'required|max:255',
            'body'  => 'required',
            'slug'  => 'required|max:100',
            'tags' => 'exists:tags,id',
            'categories' => 'required'
        ]);
    }
SQLSTATE[HY000]: General error: 1364 Field 'category_id' doesn't have a default value (SQL: insert into `posts` (`title`, `body`, `slug`, `image_url`, `user_id`, `updated_at`, `created_at`) values (STOFF, <p>get better</p>, thps, vol4_1608502655.jpg, 1, 2020-12-20 22:17:35, 2020-12-20 22:17:35)) 

Back at the "posts" table, the column name is: category_id, and this column is also included inside the $fillable property on the Post model.

After doing all this, I can read the data from my html form view, so Im able to select it, and I can manage to add a category, manually, to a post (inside SequelPro) but im just not able to send it through the HTML so, im confused did I forget to add it somewhere else, or are my namings mixed up somehow?

0 likes
2 replies
Nakov's avatar
Nakov
Best Answer
Level 73

@warpig since you have category_id in your posts table, that means that a Post belongs to a single category.

What you are trying to do with the way you are handling it now is attach multiple categories to a single post.

So instead of name="categories[]" you should have name="category_id" I guess that's a <select>element, and allow only 1 to be selected.

Same for the validation, change it everywhere, and get that one from the request. Also make sure that in your Post model, you have category_id in your $fillable array.

warpig's avatar
Level 12

Yep, in fact that was the case, I wasn't trying to attach "multiple" categories, i mixed the tags concept with categories somehow, thanks for the help!

I hope you could help me even further in the case of displaying the string name to a view, right now this won't work:

  <div class="posts-index">
    @forelse ($posts as $post)
      @foreach ($posts->category_id as $category)
        <p> Posted in: {{ $category->name }} </p>
      @endforeach
    <div class="post-desc">
      <h1> {{ $post->title }} </h1>
      <p> {{ substr(strip_tags($post->body), 0, 300) }}{{ strlen(strip_tags($post->body)) > 300 ? "..." : "" }} </p>
      <div class="button-area">
        <a href="/posts/{{ $post->slug }}"> 
          <button class="btn-readmore"> Read more </button>
        </a>
      </div> <!-- Button area end -->
    </div> <!-- Post description end -->
    @empty
      <p class="empty-msg"> No relevant posts yet </p>
    @endforelse
  </div> <!-- Posts index end -->
  <div class="paginate">
    <p> 
      
    </p>
</div>

Says: Undefined property: Illuminate\Pagination\Paginator::$category_id (View: /Users/eduardocoello/Projects/newport/resources/views/posts/index.blade.php) is this because im trying to add a foreach inside a forelse? Thanks for the help! Cheers!

Please or to participate in this conversation.