Azwan Abdullah
Azwan Abdullah

Reputation: 63

Laravel 5.6 ErrorException Trying to get property 'slug' of non-object

I'm getting the error Trying to get property 'slug' of non-object (View: C:\laragon\www\mides\resources\views\products\edit.blade.php)

In the Model,

class Product extends Model
{
    // protected $primaryKey = 'slug';

    // public $incrementing = false;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'slug', 'description', 'image', 'user_id',
    ];

    /**
     * Get the route key for the model.
     *
     * @return string
     */
    public function getRouteKeyName()
    {
        return 'slug';
    }
}

In Controller,

 public function edit(Product $product)
    {
        $product = Product::where('slug', '=', $product)->first();

        return view('products.edit')->with('product', $product);
    }

public function show(Product $product)
    {
        $product = Product::where('slug', '=', $product)->first();

        return view('products.show')->with('product', $product);
    }

In the view, (edit.blade.php)

<form role="form" method="POST" action="{{ route('products.update', $product->slug) }}">

In routes/web.php,

Route::prefix('/account')->group(function () {
    Route::get('/products', 'AccountController@products');
    Route::get('/add-product', 'ProductController@create');
    Route::get('/edit-product-{slug}', 'ProductController@edit');
    Route::put('/update-{slug}', 'ProductController@update');
});

Route::resource('products', 'ProductController');

As you can see, instead of using default CRUD resource URL, I define my own URL to go into the specific CRUD action. I'm also tried to change the $product->slug to $product->id but the results is same, I got that error.

What I'm missing here? Btw, I'm new to Laravel.

Thanks in advance.

Upvotes: 2

Views: 7065

Answers (1)

DevK
DevK

Reputation: 9942

If you want to use route model binding, you have to match the route parameter name to the method argument (or use explicit binding)

Change this:

Route::get('/edit-product-{slug}', 'ProductController@edit');

To this:

Route::get('/edit-product-{product}', 'ProductController@edit');

And then the found product will be passed to the controller method, so no need to query it:

public function edit(Product $product)
{
    return view('products.edit')->with('product', $product);
}

Upvotes: 4

Related Questions