Laravel Model data not available in Controller - php

I'm new to Laravel. I might be making a basic mistake here but I've been trying and researching for a while, need some guidance here.
I have 2 routes:
Route::get('ordercontents/{ordercontent}', 'App\Http\Controllers\OrderContentsController#edit');
Route::get('ordercontents/delete/{ordercontents}', 'App\Http\Controllers\OrderContentsController#destroy');
Inside OrderContentsController.php I have the 2 functions, one to edit a record and another to delete it.
public function edit(\App\Models\Order_content $ordercontents)
{
dd($ordercontents); //the attributes will come out empty
$orderContentId = $ordercontents->id;
$ocs = getOrderContentDetails($orderContentId);
return view('ordercontents.edit')->with('ordercontents', $ocs);
}
public function destroy(\App\Models\Order_content $ordercontents)
{
$orderId = $ordercontents->order_id;
$ordercontents->delete();
return redirect('/new-ordercontent/' . $orderId)->with('success', 'Material removido da ordem de serviço!');
}
The model exists and is called Order_content.
Everything works well for the destroy function.
However, I'm struggling with the edit function.
If I do a dd($ordercontents); the attributes array of the object comes empty inside the edit function.
What am I missing? Thanks!

You have to make sure the name of the variable that is type-hinted in your method signature matches the route parameter for Route Model Binding:
"Laravel automatically resolves Eloquent models defined in routes or controller actions whose type-hinted variable names match a route segment name." - Laravel Docs
The method signature for edit can be adjusted to match the route parameter name:
public function edit(\App\Models\Order_content $ordercontent)
When these do not match you will have Dependency Injection happening so a new non-existing Model instance would be injected.
Laravel 8.x Docs - Routing- Route Model Binding - Implicit Binding

Related

How to rename route key with model binding in PHP Laravel 8 (incorrect plurals)?

I have a Laravel 8 project where I have a model called FieldOfStudy, but the problem is that the plural of this class's name should be fields of study instead of field of studies. That causes a problem when creating an API endpoint with the following route:
Route::apiResource('fields-of-study', FieldOfStudyController::class);
The thing is, that I have a resource controller's method FieldOfStudyController::show() like this:
public function show(FieldOfStudy $fieldOfStudy)
{
dd($fieldOfStudy);
}
This will show me, that $fieldOfStudy contains a "blank" model, not the desired instance from the database. When I checked the route parameters, I found out, that the id of the model is stored as fields_of_study instead of field_of_study.
I tried to rename the parameter (didn't work - binding fails):
Route::apiResource('fields-of-study', FieldOfStudyController::class)->parameter('fields_of_study','field_of_study');
When I rename the parameter of the show() method, it works, but it's not really pretty:
public function show(FieldOfStudy $fieldsOfStudy) { }
How can I properly adjust my code to:
keep the URI in the correct plural (i.e. /fields-of-study),
keep the show() parameter name in the correct singular (i.e. $fieldOfStudy) and
don't mess the model-binding mechanism for typed parameters like show(FieldOfStudy $fieldOfStudy)?
Thank you :)
You can manipulate Laravel explicit binding:
RouteServiceProvider.php
public function boot()
{
Route::model('fields-of-study', FieldOfStudy::class);
}

Laravel 5.8 - Specified type Model for route paramteters

I have a routing conflict issue in my Laravel application (version 5.8).
Here are the 2 routes that are problematics :
Route::post('/projets/{projet}/{redirect}','ProjetController#update')->name('projets.update');
Route::post('/projets/export/excel', 'ProjetController#exportExcel')->name('projets.exportExcel');
The first parameter "projet" is supposed to be a Model Object "Projet" and "redirect" is a String.
But i don't have specified the type of these parameters and i would like to know if someone have an idea on how i can specified that the "projet" parameter is an Object "Projet" (if this is possible ?).
Thanks in advance
I think, in your ProjetController update method you can use this signature:
public function update(Request $request, App\Projet $projet, string $redirect){
// Use posted values with $request Object,
// Use $projet model
// Use $redirect string
}
And you can explore details in documentation.

Resource Controller methods with model as parameter not working

As in the basic Laracasts.com tutorial (Laracast 5.7 from scratch) I'm trying to use the following methods public function show(prototypes $prototypes) parameter to construct a view. However my view is created correctly but $prototypes is null.
The route works well(/prototypes/1/edit) and I ensured that a prototype object with the id 1 exists.
I found some older solution which stated to use something like (integer $id) as parameter but this leads to some more code. It should work like this:
Controller:
public function edit(prototypes $prototypes)
{
//
return view('prototypes.edit', compact('prototypes'));
}
According to Laracast From Scratch this should work.
Do you know how I could fix this?
What mechanism is behind this that the prototypes.edit method knows how to use the correct parameter?
For the Implicit Model Binding to works the injected variable name should match the route parameter name, in your case I think that your parameter name could be {prototype}, you can verify it by issuing the command php artisan route:list in the console.
If that is true you have to change the variable name to $prototype (please note the singular) in your controller function to match the parameter name {prototype}, like this:
public function edit(prototypes $prototype)
{
return view('prototypes.edit', compact('prototype'));
}
Update: BTW the laravel convention on Model's name is singular camel case, in your case your Model should be named Prototype not prototypes, i.e.:
public function edit(Prototype $prototype)
{
return view('prototypes.edit', compact('prototype'));
}
In order to inject the Prototypes model into the controller variable $prototypes, Laravel is expecting a matched name from the route to the input of the method. So in your routing, this:
/prototypes/1/edit
Needs to be
/prototypes/{prototypes}/edit
in order for the edit method to inject the correct instance of your prototypes model.

Laravel Route Group Second Parameter?

I updated my project from laravel 5.5.* to 5.5.43... Before the update everything was ok. But after the update, I see a warning message in route/web.php.
It says: Required parameter $routes missing.
But everything is working fine. Then when I put an empty string in the second parameter warning message gone.
So my question is:
What should I put in the required second parameter?
If it's required then why everything is working fine? It should be optional.
This is actually pretty hard to follow in Laravel. Your IDE is pulling the group definition from Router instead of RouteRegistrar.
Inside Router.php:
public function group(array $attributes, $routes)
This supports the older style of route group definitions where middleware are defined in attributes and your routes closure would be the 2nd argument.
Inside RouteRegistrar.php:
public function group($callback)
This is the new style where group only accepts the closure.
I don't like the fact that they used a condition in __call instead of defining a method for middleware, but when you call Route::middleware, the facade forwards to Router and Router::__call is returning a RouteRegistrar instance because of this line:
if ($method == 'middleware') {
return (new RouteRegistrar($this))->attribute($method, is_array($parameters[0]) ? $parameters[0] : $parameters);
}

How do I use Method Overloading in Laravel Controller?

I am trying to use method overloading feature in my laravel controller class. here is my methods
# Load Customer Balance View
public function createBalance()
{
return view('customer.balance');
}
# Load Customer Balance View
public function createBalance($CustomerID)
{
// show balance of the the defined customer
}
Here is my route -
// customer balance
Route::get('Customer/Balance', 'CustomerController#createBalance');
Route::get('Customer/Balance/{ID}', 'CustomerController#createBalance');
But it shows the error -
FatalErrorException in CustomerController.php line 45:
Cannot redeclare App\Http\Controllers\CustomerController::createBalance()
Any solution please ?
Consider use default parameters:
public function createBalance($CustomerID=null)
{
if ($CustomerID==null)
return view('customer.balance');
else
// show balance of the the defined customer
}
And change your route to:
Route::get('Customer/Balance/{CustomerID?}', 'CustomerController#createBalance');
Adding a "?" after the argument, Laravel understands you're passing an optional parameter.
You need to have different method names. This doesn't follow basic routing conventions either. The first createBalance method should probably be the index method.
I think createBalance() method alredy exist in your CustomerController so you should create new method or different name method and also change in route file with new method name.

Categories