MethodNotAllowedException when send post form with csrf_token Laravel 5.4 - php

I'm trying to access my "store" (POST) method from my route resource. I call the ProductCRUD.store method from a form that can have different input depending on the previous page. I mean by that, depending if the object i receive have certain boolean value, the input is shown.
#if($category->havePrice == 1)
{!! Form::label('price', 'Price') !!}
{!! Form::text('price', '', array('id' => 'price', 'name' => "price") !!}
#endif
When I click on the button to send the form, I got a message saying
MethodNotAllowedHttpException in RouteCollection.php line 251:...
I tried to add a csrf token with the method csrf_field() too.
I tried to empty the cache of laravel with those two methods:
php artisan cache:clear
php artisan route:cache
I tried to create a personal route like this:
Route::post('/product/store', array('as' => 'product', 'uses' => 'ProductController#store'));
None of those solution works. Always that exception.
My current code:
Route:
Route::resource('ProductCRUD','ProductController');
Form
<form method="POST" action="{{route('ProductCRUD.store')}}">
{{ csrf_field() }}
Controller method:
public function store(Request $request) {
$newGameModel= new GameModel();
$category = $this->CategoryRepo->getByID($request->category);
$this->validate($request, [
'name'=> 'required',
'picture'=> 'required|image|mimes:jpg,jpeg,gif,png|max:5000',
'quantite' => 'required|min:0',
'price' => 'required_if:'.$category->havePrice.',1',
]);
...
}
If I remove the "$this->validate(...)" method the code continues to execute (no more MethodNotAllowedException error). I tried to comment one by one validation it changes nothing.
Plus, if I reload the page, the input error are shown correctly. If i click again to send the form, surprise! The error again.
Edit:
I send my form using only a button and the form, no ajax:
{!! Form::submit('Next step', 'name'=>"accept", 'methode' => "post")) !!}
Plus, I can access my controller code. If I remove the validate method, everything work find
Do you guys have any idea why it's doing that? Thank you for your time!

Ok, so I found the problem and how to fix it (not what I wanted to do).
First, I don't have any error in my code. My post, csrf and my routes are all good.
The problem is how larval validates things. For example, If your first page was a post form and your second page is also a post form, when you validate on the second page and it fails, it will try to return to the second page to show the error. But the fact is, it can't find the response of your first page, so you got an error like I got.
I fix it by removing the first form (it was, for me, a little information I can put somewhere else). But I don't know if there is a better way to fix it.

Related

Laravel create controller method to update 1 column from 1 row

I am making a website for a dog shelter, and I want to make a button which would mark the dog as adopted. In other words, I am trying to update 1 column from 1 row. It will always be set from false to true.
I have tried making my own method in my existing controller, adding a route and creating a form, but I get errors that some other fields are also required, which are the same required fields when I would create a new dog (name, sex, DoB etc).
Code of the method in my controller:
public function markAsAdopted(Request $request, $id){
$pet = Pet::table('pets')->where('id', $id)->update(['is_adopted' => true]);
return redirect("/pets/$pet->id")->with('success', 'Successfully marked as adopted');
}
Code of the route:
Route::patch('/pets/{id}', 'PetsController#markAsAdopted');
Code of the form:
{!! Form::open(['action' => ['PetsController#markAsAdopted', $pet->id], 'method' => 'POST', 'class' => 'float-right ml-1 mr-1']) !!}
{{Form::hidden('_method', 'PATCH')}}
{{Form::submit('Mark as adopted', ['class' => 'btn btn-success'])}}
{!! Form::close() !!}
The form is on the page /pets/{id}
I have created all the other routes in this controller with the --resource flag when creating the controller, so the skeleton of CRUD was there.
Did I miss something? OR is there a better way of doing this?
Laravel is routing the markAsAdopted call to your update() (or possibly create() depending on how you have your Routes set) instead of the markAsAdopted() method. This is, in turn, calling your PetsRequest class (or whatever you've called your verification class).
It is most likely coming in as a POST and possibly ignoring the PATCH method, thus routed to update(). You can do a couple of things - move the patch method higher in Routes file and test by changing to POST. If this works, you know this is the problem. This is just a test - you will break the other pets POST coming in below it in the Routes file, so remember to change it back :)
I typically skip the PATCH thing altogether though, as I've run into similar issues. I normally just make a POST route with a special name (e.g. Route::post('/petsMarkAsAdopted/{id}', 'PetsController#markAsAdopted');) and open the form with the url to that special route.
If you really want to keep the PATCH, do the higher placement test above, and you can use blade to set the method after you open your form, like so:
#method('PATCH')
Edit: As noted in the comments, the above fixes the routing, but there is a different problem in your controller method now that we can access it. Take out the table(), and just call the model to get the pet your need. I've separated out the call for clarity:
$pet = Pet::where('id', $id)->first();
$pet->update(['is_adopted' => true]);

Laravel error upon submitting a form: MethodNotAllowedHttpException in RouteCollection.php line 218. What could this be due to?

There is a form in my view, from where, on clicking submit, data is taken to ajax script which is supposed to invoke the controllers specified in the post routes in routes.php. The controllers are expected to process the received data and throw the result back to the view. Why is this error occurring immediately after submitting the form and things aren't working as expected>
Check your routes.php file. Make sure that the method your using corresponds with what you have allowed.
Here is the laravel documenation for routes
For example, if your request is a GET request, the call should look like this in the routes file:
Route::get('/test-get-url', function () {
// Matches The "/test-get-url" URL using a GET method
});
And for post
Route::post('/test-post-url', function () {
// Matches The "/test-post-url" URL using a POST method
});
Go to terminal/cmd..whichever you using and type
php artisan route:list
this will list all your routes and check at what route your is being submitted.Note the corresponding method to be used in the Method column and use that method while submitting form.I'm assuming it's PUT method(which is most likely).Ex--
Use method attribute if you're using simple HTML code like--
<form action="{{route='..'}}" method="PUT">
or if you're using form helper then use--
{!! Form::open($post, ['route' => ['..'], 'method' => 'PUT']) !!}
Go to your route.php file and check
Route::get('someroute',['uses'=>'somecontroller#function_get','as'=>'some_get']);
Route::post('someroute',['uses'=>'somecontroller#funtion_post','as'=>'some_post']);
make sure if your are using (as) in you routes its different and also where you use your ajax you properly define your route where you want to post your form data and it's type is same as you mention in routes and one more thing check you properly use (;) in your code
hope this will help you fell free to ask your query

Using Form button/Eloquent to set an entire column to null

I am having a real issue getting a button to scan and clear out an entire column using an eloquent model. I have two columns in my SQLite DB, "States" and "Totals"... I want the States to stay in their own order, but I want the totals to be cleared out upon the user selecting a button. The character type for 'totals' is BigInt... After the user selects the button, I want them redirected to the home page (with the values cleared so they can start over).
Here are my routes:
Route::resource('states', 'StateController');
Route::get('/', 'StateController#index');
Route::post('create', 'StateController#store');
Route::post('states.update', 'StateController#update');
Here is my controller:
public function update()
{
Distributors::update(['total' => null]);
return View::make('states');
}
Here is my form:
{{ Form::open(['route' => 'states.update']) }}
{{ Form::submit('Destroy and Start Anew') }}
{{ Form::close() }}
The error I get is:
MethodNotAllowedHttpException
Is there a simple issue with my routes? I can't figure it out.
You did not specify a method attribute on your form, so it will automatically execute a GET request. Your state.update route is only setup to accept POST requests.
Change your form to this:
{{ Form::open(['route' => 'states.update', 'method' => 'post']) }}
Please delete
Route::resource('states', 'StateController');
in your route and try again.

Extra strange segment in a form action URL automatically added by laravel

I have this form:
{!!Form::open(['route'=>'fastsearch.show'])!!}
In routes.php I have:
Route::resource('fastsearch','SearchController');
And in SearchController i have a method show() that sends the return to a view called fastsearch (which is fastsearch.blade.php)
If I look into the source of the page where the form is, I see this:
<form method="POST" action="http://localhost:8000/fastsearch/%7Bfastsearch%7D" accept-charset="UTF-8"><input name="_token" type="hidden" value="hLcSkGk2p5XfTkFEv2pwGgcVQB18vHQIGMpOVGpM">
If I put some data in the form and click Submit, I get this error:
MethodNotAllowedHttpException in RouteCollection.php line 201:
My question is why the extra segment in the action URL (this one: /%7Bfastsearch%7D). Is something wrong with the routes ?
(Just to give you all the details, this a general search form that lies on almost every page in order to allow the users to run a quick search from almost every page they might be at that time. So it doesn’t matter if you’re on Home page or on /Home/Subpage/SubSubPage{wildcard}{wildcard} you can still see the form and use it)
You're trying to send a post request to a route expecting a get request.
Change:
{!! Form::open(['route'=>'fastsearch.show']) !!}
To:
{!! Form::open(['route'=>'fastsearch.index']) !!}
Where index is the name of the action you wish to receive the post request.
You're probably better off using specific named routes for this though.
Route::post('fastsearch', [
'as' => 'fastsearch.search', 'uses' => 'SearchController#search'
]);
Take a look at http://laravel.com/docs/5.1/controllers#restful-resource-controllers for more info on resource controllers and http://laravel.com/docs/5.1/routing#named-routes for more on named routes.
You can also use ./artisan route:list for a list of existing routes.

Laravel 5 Form parameter issue

Ok so I have added in the Form functionality just fine in Laravel 5 and have been using it through out these tutorials. I am brand new to Laravel in general and can't see to find out what is going wrong. I have a nested route that is todos.items.create, so to create a new item in that list I would have to pass that ID into the Form::open tag. However when doing so I get a Whoops, looks like something went wrong. Now if I remove the $todo_list->id parameter the page loads fine but with it I always get this error. Here is my code
Controller:
public function create($list_id)
{
$todo_list = TodoList::findOrFail($list_id);
return view('items.create', ['TodoList' => $todo_list]);
}
Create View (create.blade.php in side my items folder inside the views folder)
{!! Form::open(array('route' => ['todos.items.store', $todo_list] )) !!}
When just doing the below it renders fine but doing the above which is needed it doesn't. This is because I need the id of the list in which to create the new item in.
{!! Form::open(array('route' => ['todos.items.store'] )) !!}
Routes:
Route::get('/', 'TodoListController#index');
Route::resource('todos', 'TodoListController');
Route::resource('todos.items', 'TodoItemController', ['except' => ['index', 'show'] ]);
Any ideas what I am doing wrong here? I have ran a var_dump of $todo_list->id before the return of the view just to check things and it returned the proper id.
You've created the $todo_list object but have passed it to your view as $TodoList.
Try using the following instead
return view('items.create', ['todo_list' => $todo_list]);
When calling the view from the controller, the key used in your array of data is what the variable will be available as on the pages.

Categories