I want to store books, with title, year and already existing Author. An author is saved in a table authors that have a one to many relationship with books table. To create a book i have a from with two text inputs and one select. Select is filled from database.
Now i want to store them and attach the author immediately.
I can’t pass the author in the route because it’s dynamically due the select-input.
Is there a possibility to do it like the call below?
Route:
Route::post('/store', [BookController::class, 'store'])->name('book.store');
Controller:
public function store(Request $request,Author $author_id)
{
$validated = $request->validate([
'title' => 'required',
'year' => 'required',
'book_id' => 'required'
]);
Book::create($request->all());
return redirect()->route('book.index');
}
2
Answers
Second parameter must be sent in order to get Model from authors table.
Unless you modify your route to accept params and add JS listener to form on submit, change action URL with selected author, it is not possible per my knowledge..
Since you are not doing anything with Author model, maybe you can just add validation for author_id => "required,exists:authors" ?
If I understand correctly, you want to use route model binding for your
Author
, but that value is chosen with a<select>
on the form.Here’s a solution to do that; if you don’t have to use route model binding, it is much simpler, see the second solution below.
Route model binding solution
For route model binding, you’ll need a route like this:
So you need to know the author ID to generate the form
action
URI – which you can’t do at page load time because the user has not chosen an author yet. One way to solve this is with Javascript – every time theselect
chages, find the selected author, and update the form’saction
.Here’s a working HTML/JS snippet which does that, though you’ll need to look at the form in your browser’s developer tools to see the action changing.
And now, assuming you use the route, form, and Javascript shown above, and that you have your
Author
<->Book
relationships set up, your controller can do:Note you should probably include some kind of front end Javascript validation that checks if an author is selected, otherwise the
action
is not set and the form will post to the current URL, which will probably result in a 404.Simpler solution
If you can live without route model binding, this is trivially simple. Your existing route is fine:
Your form should include the
author_id
, exactly as in the example above.And the controller just needs 1 extra line to find the selected author: