Abdel Kdj
Abdel Kdj

Reputation: 95

Laravel: Update value of a column on button click

Hello i'm still new to laravel and I've searching the web for almost 3 hours about this issue I have I tried many things but it didn't work.

So basicly I have a page with a button , when I click that button "Approve" I want to update the value from 0 to 1 (the column is of type boolean). This is my controller :

public function approve($id){
    $training = Training::find($id);
    $training->update(['Approved' =>'1']);


    // $training->Approved = 1;
   // $training->save();
    return redirect('/trainings')->with('success', 'Training Approved');
}

This is page section with the button it's in the folder trainings and has the name " show.blade.php" :

 {!!Form::open(['action' => ['TrainingsController@approve',$training->TrainingsID], 'method' => 'POST','class' => 'pull-left'])!!}
            {{Form::hidden('_method','PUT')}}
            {{Form::submit('Approve',['class' => 'btn btn-success'])}}

    {!!Form::close()!!} 

and the routes (I guess this is the part I'm doing wrong):

Route::post('/trainings',['as' =>'trainings.show', 'uses' => 'TrainingsController@approve']);

The error I get when clicking the button is this :

Symfony \ Component \ HttpKernel \ Exception \ MethodNotAllowedHttpException

Thank you for your Help

Upvotes: 3

Views: 7136

Answers (2)

common sense
common sense

Reputation: 3898

You don't need method spoofing here, since you using a POST action. Its only necessary for PUT, PATCH, DELETE.

Your current route definition is wrong because you connect trainings/show with the approve action. In fact it should be a show action.

This is the code which should work (untested)

class TrainingsController extends Controller 
{
    public function show(Training $training) // Using Route Model binding here 
    {
         return view('trainings.show', ['training' => $training]);
    }

    public function approve(Training $training) 
    {
        $training->update(['Approved' => '1']);

        return redirect()->route('trainings')->with('success', 'Training Approved'); // if you want to redirect to a list of all trainings and would need an index action
        // return redirect()->route('trainings', ['training' => $training])->with('success', 'Training Approved'); // if you want redirect to detail page of this training
    }
}

routes/web.php

Route::post('trainings/{training}/approve', ['as' => 'trainings.approve', 'uses' => 'TrainingsController@approve']); 
Route::get('trainings/{training}', ['as' => 'trainings.show', 'uses' => 'TrainingsController@show']);

Blade

{!!Form::open('route' => ['trainings.approve', $training->TrainingsID], 'class' => 'pull-left'])!!}
    {{Form::submit('Approve',['class' => 'btn btn-success'])}}
{!!Form::close()!!} 

Some remarks on your code:

  • an ID like TrainingsID is redundant because you already know that is the ID of training
  • stick to snake_case table / attribute names for your model/db fields

Upvotes: 1

Alexey Mezenin
Alexey Mezenin

Reputation: 163748

Since the route is post, you should change form method to post too:

{{ Form::hidden('_method','POST') }}

Or:

{!! Form::open(['method' => 'post', 'action' => ....

You also need to add id to the route definition:

Route::post('trainings/{id}', ['as' => 'trainings.show', 'uses' => 'TrainingsController@approve']);

Upvotes: 1

Related Questions