Reputation: 256
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.
Upvotes: 3
Views: 2531
Reputation: 4032
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:
OR
Request
object to resolve the Item
instead.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');
}
Upvotes: 2