I have a view that list all objects in a database and for each object creates a form for saving to a different table. My problem is, that the value isn't being passed to my function.
Here is my blade.php file:
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-12">
<div class="card">
<div class="card-header">{{ __('Items') }}</div>
<div class="card-body">
<div class="row">
@foreach($items as $item)
<div class="col-md-3 col-xs-12">
<div class="card">
<img src="..." class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">{{ $item->name }}</h5>
<p class="card-text">$ {{ $item->price }}</p>
@auth
<form method="post" action="{{ route('carts.store', $item) }}">
@csrf
@method('post')
<button type="submit" class="form-control btn">add to cart</button>
</form>
@endauth
<form method="post" action="{{ route('item.destroy', $item) }}">
@csrf
@method('delete')
<button type="submit" class="form-control btn btn-danger">delete</button>
</form>
</div>
</div>
</div>
@endforeach
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
and my function in the CartsController:
public function store(Item $item)
{
$cart = new Cart();
$cart->user_id = auth()->id();
$cart->item_id = $item->id;
$cart->save();
return redirect('/item');
}
When I click on add to cart I get this error:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'item_id' cannot be null (SQL: insert into `carts` (`user_id`, `item_id`, `updated_at`, `created_at`) values (1, ?, 2020年08月24日 07:35:44, 2020年08月24日 07:35:44))
I've tried passing the id to the function directly but that also doesn't seem to work. I'm very confused as to why this is happening since I can use $item two rows earlier without a problem.
1 Answer 1
Provided that your route model binding is setup correctly, it won't actually matter whether you pass the id of an object or the object itself to the the route() function.
https://laravel.com/docs/7.x/routing#implicit-binding
When you run php artisan route:list, you should see something similar to this:
POST | cart/store/item/{item} | carts.store | App\Http\Controllers\CartController@store
Laravel automatically resolves Eloquent models defined in routes or controller actions whose type-hinted variable names match a route segment name.
So any of the following will actually work
{{ route('carts.store', $item) }}
OR
{{ route('carts.store', $item->id) }}
OR
{{ route('carts.store', ['item' => $item->id]) }}
Should all resolve to the same thing.
Addendum
So the route you are using doesn't have a route parameter for your item (i.e {item}), as such it won't know which Item object you are referencing.
You can either:
- Amend your route to include this route parameter
OR
- use the
Requestobject to resolve theIteminstead.
Blade
<form method="post" action="{{ route('carts.store') }}">
@csrf
@method('post')
<input type="hidden" name="item_id" value="{{ $item->id }}">
<button type="submit" class="form-control btn">add to cart</button>
</form>
Controller
public function store(Request $request)
{
$cart = new Cart();
$cart->user_id = auth()->id();
$cart->item_id = $request->item_id;
$cart->save();
return redirect('/item');
}
2 Comments
php artisan routes:list returns this POST | carts | carts.store | App\Http\Controllers\CartsController@store | web The $fillable array is also set up correctly. But it's still not working
$item->idas inaction="{{ route('carts.store', $item->id ) }}".