Ad

Laravel Route Model Binding Return Id Null On Product Deletion

- 1 answer

I'm using laravel 5.1.28. Here I'm just trying to create a simple application that can add, delete, and edit products but I noticed that when using the binding model, the $product instance just return null. I'm going to explain next, but first here are the full codes (without blade):

In my route.php I have the following route for product:

Route::model('products', 'App\Product'); 

Route::group(array('prefix' => 'admin', 'middleware' => 'SentinelAdmin'), function ()
{

# Product Management admin backend
Route::group(array('prefix' => 'products'), function () {
    Route::get('/', array('as' => 'products', 'uses' => '[email protected]'));
    Route::get('create', '[email protected]');
    Route::post('create', '[email protected]');
    Route::get('{productId}/delete', array('as' => 'delete/product', 'uses' => '[email protected]'));
    Route::get('{productId}/confirm-delete', array('as' => 'confirm-delete/product', 'uses' => '[email protected]'));
    Route::get('{productId}/restore', array('as' => 'restore/product', 'uses' => '[email protected]'));
    Route::get('{productId}', array('as' => 'products.show', 'uses' => '[email protected]'));
});

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

});

So, this is my simple database migration:

class CreateProductsTable extends Migration
{

public function up()
{
    Schema::create('products', function (Blueprint $table) {
        $table->increments('id');
        $table->string('user_id');
        $table->string('name');
        $table->string('description')->nullable();
        $table->string('category')->nullable();
        $table->decimal('price')->nullable(); 
        $table->integer('quantity')->nullable(); 
        $table->tinyInteger('in_stock')->nullable(); //0 - no, 1 - yes
        $table->string('photos')->default('default_product_photo.jpg')->nullable(); //add one first
        $table->timestamps();
    });
}
public function down()
{
    Schema::table('products', function (Blueprint $table) {

    });
}
}

In my Product.php model, I have this:

**class Product extends Model
 {
   protected $table = 'products';
   protected $guarded = ['id'];
   protected $fillable = [
    'user_id',
    'name',
    'description',
    'category',
    'price',
    'quantity',
    'in_stock',
    'photos',
];
}**

This are the 2 functions that I have in the ProductController.php

For the 1st FUNCTION getModalDelete below, it will find the product id, and display a confirmation box to delete the product. If confirmed button is clicked, the route delete/product/{id} will be called and the destroy method is then called the (2nd function). The 2nd function is matter:

class ProductController extends Controller
{
  //1st FUNCTION
  public function getModalDelete(Request $request, $id) 
  {
    $product_id = Product::where('id', '=', $id)->firstOrFail();
    $model = 'products'; ////testing s
    $confirm_route = $error = null;
    try {
        $confirm_route = route('delete/product', ['id' => $product_id]);
        return View('admin/layouts/modal_confirmation', compact('error', 'model', 'confirm_route'));
    } catch (ProductNotFoundException $e) {

        $error = trans('product/message.error.delete', compact('id'));
        return View('admin/layouts/modal_confirmation', compact('error', 'model', 'confirm_route'));
    }
  }

  //2nd FUNCTION
  public function destroy(Product $product)
  {
    Product::destroy($product);
   // $product->forceDelete(); //doesn't work either

    //dd($product); //Weird that it returns null.

    //$success = Lang::get('products/message.success.delete');

    //return Redirect::route('admin.products.index')->with('success', $success);

  }
}

But if I changed the parameter of the function from

public function destroy(Product $product)
{
}

to

public function destroy($id)
{
}

it works. But I just don't know why the parameter (Product $product) doesn't work here using route model binding. The $product just return null. but the $id returns a value.

Ad

Answer

Found out it was the issue on front end template:

Actually I tried changing from

Route::model('products', 'App\Product'); 

to

Route::model('product', 'App\Product'); 

before attempted to post this question and it did not work due to the issue of the frontend template that I'm using. So, the answers from @Mark Davidson changing the

Route::model('products', 'Product');

to

Route::model('product', 'Product');

and changing the parameter of

{productId} 

to

{product}

works perfectly.

The route of deleting the product in the front end has some issue. I can delete the product using the URL browser but clicking on the delete button doesn't popup and I was unable to debug the value. Somehow, the button popup appear if I change the

Route::model('product', 'App\Product'); 

to

Route::model('products', 'App\Product');

but it returns the $product instance to null. Problem solved.

Ad
source: stackoverflow.com
Ad