Update Method in Laravel - laravel

I'm new to Laravel. I am using laravel 5.4 and trying to validate and update data in a model. Code looks like this:
Route
Route::resource ('contribution-structure', 'ContributionStructureController');
ContributionStructureController
public function update(Request $request, $id)
{
//
$data = $this->validate($request, [
'employer_name' => 'required|min:3',
]);
$plansubmission = PlanSubmission::find($id);
$plansubmission->update($data);
}
The validation works but when I update I get an error saying:
Argument 1 passed to Illuminate\Database\Eloquent\Model::update() must
be of the type array, null given, called in
C:\xampp\htdocs\tapp\app\Http\Controllers\ContributionStructureController.php
on line 84 and defined

The validator doesn't return anything in versions earlier than Laravel 5.5. To get your code to work I would recommend updated to that latest version. Especially for new projects, you should always start with the latest stable version.
If you don't want to update you need to pull the data from the request after validating.
public function update(Request $request, $id)
{
$this->validate($request, [
'employer_name' => 'required|min:3',
]);
$data = $request->only('employer_name');
$plansubmission = PlanSubmission::find($id);
$plansubmission->update($data);
}

Today i told about the update method in php framework laravel there is an error message gives when we apply update method in laravel
when we build the update method to update the data of the database table we face some issues for example
The controller does not fetch the id
The Route problem which route is good PUT, get, Post, Patch
and the laravel version problem
first the controller issue
public function Delivery_charges_update(Request $request, $id)
{
// return $request->all();
$request->validate([
'start-km' => 'required',
'end-km' => 'required',
'amount' => 'required',
]);
$data = Deliverycharges::find($id);
$data->start_km = $request->get('start-km');
$data->end_km = $request->get('end-km');
$data->amount = $request->get('amount');
$data->update();
return redirect('/SuperAdmin/Delivery_charges');
}
then second the route issue you can make route by post method because it is best
Route::post('/Delivery_charges_update/{id}', 'SettingController#Delivery_charges_update');
then third the laravel version issue
so the latest version of laravel is 5.5
and this all issues solution is valid for this laravel version

Related

Laravel validation couldn't store value after validate and give error 500

I have a form that using ajax for update data client. In that form there is an input file. Everything is going fine except for updating the file. File is sent, it changed on storage too, but it gives error on validation and didn't change data on database.
Here is the code on the controller :
public function update(Request $request, Client $client)
{
$validatedData = Validator::make($request->all(), [
'name' => 'required|max:255',
'logo'=> 'image|file|max:100',
'level' => 'required|max:1'
]);
$validatedData['user_id'] = auth()->user()->id;
if ($validatedData->fails()){
return response()->json($validatedData->errors());
} else {
if($request->file('logo')){
if($request->oldLogo){
Storage::delete($request->oldLogo);
}
$validatedData['logo'] = $request->file('logo')->store('logo-clients');
}
$validateFix = $validatedData->validate();
Client::where('id', $client->id)->update($validateFix);
return response()->json([
'success' => 'Success!'
]);
}
}
It gives error on line :
$validatedData['logo'] = $request->file('logo')->store('logo-clients');
With message :
"Cannot use object of type Illuminate\Validation\Validator as array"
I use the same code that works on another case, the difference is the other not using ajax or I didn't use Validator::make on file input. I guess it's just wrong syntax but I don't really know where and what it is.
To retrieve the validated input of a Validator, use the validated() function like so:
$validated = $validator->validated();
Docs:
https://laravel.com/docs/9.x/validation#manually-creating-validators
https://laravel.com/api/9.x/Illuminate/Contracts/Validation/Validator.html
$validatedData is an object of type Illuminate\Validation\Validator.
I would say the error is earlier there as well as this line should give an error also:
$validatedData['user_id'] = auth()->user()->id;
As ericmp said, you first need to retrieve the validateddata to an array and then work with it.

Laravel API routes and Controller variable

I'm a new user of Laravel, and i'm a bit confused with Laravel route API and the name of variable in the controller.
Here an example to explain :
An API route
Route::middleware('auth:sanctum')->group( function () {
Route::resource('cepage', CepageController::class);
});
For a PUT or PATCH, i have this function in the CepageController :
public function update(Request $request, Cepage $cepage)
{
$input = $request->all();
$validator = Validator::make($input, [
'libelle' => 'required',
'abrege' => 'required'
]);
if($validator->fails()){
return $this->sendError($validator->errors());
}
$cepage->libelle = $input['libelle'];
$cepage->abrege = $input['abrege'];
$cepage->save();
return $this->sendResponse(new CepageResource($cepage), 'Cépage mis à jour');
}
If you see my route name "cepage" have the same name of the $cepage variable of the function declaration in the controller, Laravel update the record in the database.
If they are no identical, Laravel create a new record in the database.
Why they need to be exactly the same ?
I think i miss something in the documenation of Laravel.
Thanks for your explanations.
It needs to be the same, for laravel to know what object does he needs to create for us.
Route::resource does a few routes for you, with the base url give into it (https://laravel.com/docs/8.x/controllers#actions-handled-by-resource-controller)
So once you have defined Route::resource('cepage', CepageController::class)
You will have the following routes defined:
Verb URI Action Route Name
GET /cepage CepageController#index cepage.index
GET /cepage/create CepageController#create cepage.create
POST /cepage CepageController#store cepage.store
GET /cepage/{cepage_id} CepageController#show cepage.show
GET /cepage/{cepage_id}/edit CepageController#edit cepage.edit
PUT/PATCH /cepage/{cepage_id} CepageController#update cepage.update
DELETE /cepage/{cepage_id} CepageController#destroy cepage.destroy
And in the controller you need to follow the naming, because in the url you have only ids of the object. But if you follow the naming, laravel will fetch the object for you by its id. See:
public function update(Request $request, $cepage_id)
{
$cepage = Cepage::find($cepage_id);
//here you have to fetch the object for yourself to access it
}
public function update(Request $request, Cepage $cepage)
{
//here you can already access $cepage variable
}

Laravel - how to retrieve url parameter in custom Request?

I need to make custom request and use its rules. Here's what I have:
public function rules()
{
return [
'name' => 'required|min:2',
'email' => 'required|email|unique:users,email,' . $id,
'password' => 'nullable|min:4'
];
}
The problem is that I can't get $id from url (example.com/users/20), I've tried this as some forums advised:
$this->id
$this->route('id')
$this->input('id')
But all of this returns null, how can I get id from url?
When you are using resources, the route parameter will be named as the singular version of the resource name. Try this.
$this->route('user');
Bonus points
This sound like you are going down the path of doing something similar to this.
User::findOrFail($this->route('user'));
In the context of controllers this is an anti pattern, as Laravels container automatic can resolve these. This is called model binding, which will both handle the 404 case and fetching it from the database.
public function update(Request $request, User $user) {
}

PUT in laravel API

I'm studying api rest with laravel, I was able to implement all methods except PUT. Although the routes and controllers are correctly configured a response to a request using the PUT method is "laravel put Sorry, the page you are looking for could not be found.", As now image.
here is the method code in the controller in app/Http/Controllers/LivroController.php:
public function store(Request $request) {
$livro = $request->isMethod('put') ? Livro::findOrFail($request->livro_id) : new Livro;
$livro->id = $request->input('livro_id');
$livro->nome = $request->input('nome');
$livro->descricao = $request->input('descricao');
$livro->user_id = 1; //$request->user()->id;
if($livro->save()) {
return new LivroResource($livro);
}}
here is the route code in /routes/api.php:
Route::put('livro', 'LivroController#store');
change your postman method to POST and then add new parameter in your Body :
"_method" : PUT
This is because HTML forms do not support PUT, PATCH or DELETE actions. So, when defining PUT, PATCH or DELETE routes that are called from an HTML form, you will need to add a hidden _method field to the form
If you want to create new data, you should use post method,
Route::post('livro', 'LivroController#store');
public function store(Request $request) {
If you want to update exist data you should use put method,
Route::put('livro/{id}', 'LivroController#update');
public function update(Request $request, $id) {
You can use this package https://github.com/durmus-aydogdu/laravel-resource for rest calls. This package highly customizable for rest and resource calls.
Is better that you use controllers type resources and for this case the put method. Also you should validate the request. For example:
public function update(Request $request, $id)
{
$livro = Livro::findOrFail($id);
$validator = Validator::make($request->all(), [
'livro_id' => 'required',
'nome' => 'required',
'descricao' => 'required',
]);
if ($validator->fails()) {
return response()->json(['errors'=>$validator->messages()],Response::HTTP_UNPROCESSABLE_ENTITY);
}else{
$livo->update($request->all());
return response()->json(['livro'=>$livro], Response::HTTP_OK);
}
}

Unable to send emails in laravel 5 app

Hello I have a laravel 5 app which is working perfectly in local environment. But in production emails are not getting sent instead I get the exception below:
1/1 FatalErrorException in AstAnalyzer.php line 125:
Cannot instantiate interface PhpParser\Parser
Path to file: /vendor/jeremeamia/SuperClosure/src/Analyzer/AstAnalyzer.php line 125
I don't get it because right now I am testing same function in local and is working. Every other path of the app is working except this one.
Below is the function:
public function update_password(Request $request, $id)
{
$this->validate($request, [
'new_password' => 'required|confirmed|min:6',
'new_password_confirmation' => 'required',
]);
$user = $this->user->get_user_by_id($id);
$password = $request->get('new_password');
$this->user->save_password($password, $id);
// Send an email informing user that we have updated his password.
Mail::queue('emails.password_update', ['user' => $user, 'password' => $password], function($message) use ($user){
$message->to($user->email, $user->name)->subject('Account Password Updated');
});
$target_location = 'users/'. $id. '/profile';
flash()->success('Password Updated Successfully');
return redirect($target_location);
}
I finally solved my problem. I ran a composer update which installed the lastest version of nikic/php-parser and equally the latest version jeremeamia/superclosure, but somehow, the class Parser which was formally use in nickic's package was now an Interface. class Multiple was now implementing the interface. So in AstAnalyzer.php in jeremeamia's package, that change was not made and instead use PhpParser\Parser as CodeParser; was used which is logical as an interface cannot be instantiated unless some binding is done. So as a quick fix, I used the previous version of nikic/php-parser.

Resources