I am trying to store store an author and genre into a Book. The way I'm trying to achieve this is by having an Author table, Genre table and a Book table. I want to store the foreign key for the author and genre into the books table.
I have created a form to store the needed information for the book. Within the form, there are two select tags and within them I loop through the authors and genres array. I use a store function in my BookController to validate the data that is being sent. After the validation, I store a new Book.
However, the foreign keys are not being stored in the database except for the primary key, title, blurb and timestamps.
Book Model
class Book extends Model
{
use HasFactory;
protected $fillable = [
'author_id',
'genre_id',
'title',
'blurb',
];
public function authors()
{
return $this->BelongsTo(Author::class);
}
public function genres()
{
return $this->BelongsTo(Genre::class);
}
}
Author Model
class Author extends Model
{
use HasFactory;
protected $fillable = [
'name',
];
public function book()
{
return $this->hasMany(Book::class);
}
}
Genre Model
class Genre extends Model
{
use HasFactory;
protected $fillable = [
'title'
];
public function book()
{
return $this->hasMany(Book::class);
}
}
BookController create()
public function create()
{
$authors = Author::all();
$genres = Genre::all();
return view('admin.book.create', ['authors' => $authors, 'genres' => $genres]);
}
BookController store()
public function store(Request $request)
{
$validatedData = $request->validate([
'title' => 'required|max:255',
'authors' => 'required|array',
'genres' => 'required|array',
'blurb' => 'required',
]);
Book::create($validatedData);
return redirect()->route('admin.book.create');
}
Books table migration
public function up()
{
Schema::create('books', function (Blueprint $table) {
$table->id();
$table->foreignId('author_id');
$table->foreignId('genre_id');
$table->string('title');
$table->string('blurb');
$table->timestamps();
});
}
create.blade.php (create Book page)
<div class="flex justify-center">
<div class="flex justify-center border lg:w-1/4">
<div class="flex flex-col justify-center lg:w-2/4 gap-2">
<form action="{{ route('admin.book.store') }}" method="post">
@csrf
<div class="mb-2">
<h1 class="text-xl">Add Book</h1>
</div>
<div>
<label class="" for="title">Title</label>
<input name="title" class="w-10 border border-gray-400 w-full py-1 px-2" type="text">
</div>
<div>
<label class="" for="author">Author</label>
<select name="authors[]">
@foreach($authors as $author)
<option value="{{ $author->id }}">{{ $author->name }}</option>
@endforeach
</select>
</div>
<div>
<label class="" for="genre">Genre</label>
<select name="genres[]">
@foreach($genres as $genre)
<option value="{{ $genre->id }}">{{ $genre->title }}</option>
@endforeach
</select>
</div>
<div>
<label class="" for="blurb">Blurb</label>
<textarea name="blurb" id="" cols="18" rows="10"></textarea>
</div>
<div>
<button class="py-2 px-4 border" type="submit">Save</button>
</div>
</form>
</div>
</div>
</div>
EDIT: When I dump and die:
array:5 [▼
"_token" => "WHlc2nvslN6l6iY4D8feeIzLEYzetMo3Ek0tLVPn"
"title" => "Harry Potter"
"authors" => array:1 [▼
0 => "1"
]
"genres" => array:1 [▼
0 => "4"
]
"blurb" => "Harry Potter is een zevendelige fantasyserie geschreven door de Britse schrijfster J.K. Rowling. De boeken volgen chronologisch de puberteit en de adolescentie ▶"
]
CodePudding user response:
You must do this:
- First, In You Blade convert select names in authors[] to author_id and genres[] to genre_id.
- Update authors and genres in validations to new names above.