0

I am working on my first laravel project, which is a library application. I am now working on a form to create a book, and I had to create many eloquent relationships here. I created the relationship languages to books, which was easy, because one book can only have one language (in this case), but one language can be used for several books. The problem I am facing now is, that I want to be able to select the genres as well on the form, so I connected the genres table with my book table with a belongsToMany relationship and of course I have also created a pivot table. Now, I think that the problem has to be in my BookController's store function, but I just can't figure out what it is.

Here is some of my code: (sorry if I'm missing something this is my first time asking a question here)

My BookController's store function:

public function store(Request $request)
    {
        $validatedData = $request->validate([
            'title' => 'required|max:255',
            'author_id' => 'required',
            'year' => 'required|numeric',
            'publisher_id' => 'required',
            'genres' => 'exists:genres,id',
            'language_id' => 'required',
            'isbn' => 'required|numeric',
            'pages' => 'required|numeric',
        ]);

        $book = Book::create($validatedData);
        $book->genres()->attach(request('genre_id'));


        return redirect('books')->with('success', 'Book was added!');
    }

If I submit my form right now I get this message:

SQLSTATE[HY000]: General error: 1364 Field 'genre_id' doesn't have a default value (SQL: insert into books (title, author_id, year, publisher_id, language_id, isbn, pages, updated_at, created_at) values (Spanish for cats, 1, 1994, 1, 1, 1234567891128, 2337, 2020-02-17 16:37:07, 2020-02-17 16:37:07)) my create.blade.php

<div class="form-group">
                <label for="genre_id">Genre(s):</label>
                @foreach($genres as $genre)
                <input type="checkbox" name="genre_id[]" value="{{ $genre->id }}">{{ $genre->name }}
                @endforeach
                </select>
                @error('genre_id')
                <div class="alert alert-danger">{{ $message }}</div>
                @enderror
            </div>

The value of the genres show up in my form, but I can't seem to input them into my database.

Any help would be highly appreciated!

mekol
  • 31
  • 5
  • 1
    Please post code as plain text in a code bock. See [Markdown help](https://stackoverflow.com/editing-help#code) – Paul Spiegel Feb 17 '20 at 17:12
  • If book <-> genre is a many-to-many relation, then you shouldn't have `genre_id` column in the `books` table. Check your migration script or the database schema. – Paul Spiegel Feb 17 '20 at 17:54

1 Answers1

0

First from your example I cannot be sure whether you intend to pass a single genre via the request data or an array of genres as using the word genres leads me to believe that there could be more than one genre but the validation key is singular, use genres.* if you intend to pass an array of genre_id values.

This is one of the downsides to Laravel's magic methods, since you are requesting $book->genres()->attach(request('genre_id')) and request('genre_id') does not appear to exist in your validation you will find that you are actually passing a null value like so $book->genres()->attach(null) which is causing the error.

To resolve this issue you should change the ->attach() call to $book->genres()->attach($validatedData['genres']) which will ensure that you are passing your validated data to the attach method.

Azeame
  • 2,322
  • 2
  • 14
  • 30