I'm having problem with the Laravel 4, nested routing. I can display the create method form but can't store. Here is the code, I'll just come to the point.
I have a base Resource Controller and another nested controller
This is in my Routes.php
Route::resource('profile','ProfileController');
Route::resource('profile.bands','BandsController');
I don't think I have to display the profile's code here, I'll show you the BandsController
public function create($profileId)
{
return View::make('bands.create',['title' => 'Create Band Profile' , 'profileId' => $profileId]);
}
This will just display the form, as you know.
The form is:
{{Form::open( [ 'route' => ['profile.bands.create',$profileId]])}}
<input class="input" type="text" name="name" value="" />
<input class="input" type="text" name="city" value="" />
<input type="submit" value="submit" />
{{Form::close()}}
Now, I didn't understand, the form action url looks good when I view it in browser but when I submit it I get, this error.
Symfony \ Component \ HttpKernel \ Exception \ MethodNotAllowedHttpException
open: E:\server\www\gigmor.com\gigmor\vendor\laravel\framework\src\Illuminate\Routing\Router.php
// The method not allowed exception is essentially a HTTP 405 error, so we
// will grab the allowed methods when converting into the HTTP Kernel's
// version of the exact error. This gives us a good RESTful API site.
elseif ($e instanceof MethodNotAllowedException)
{
$allowed = $e->getAllowedMethods();
throw new MethodNotAllowedHttpException($allowed, $e->getMessage());
}
}
What might I have done wrong ?
MethodNotAllowedHttpException means that the HTTP method you're using is not right. You're using POST on a route tha only accepts GET.
On your form, you must use the route
profile.bands.store
Your .create route is just to show a create record form, to post it you must use store.
Take a look at your routes names and methods using
php artisan routes
Related
I am new to Laravel, I am trying to have a simple example, but I am getting a 419 error, I dont know why it shows up but I will expalin what I did,
I created a simple Controller and I called it FormController with the command line :
php artisan make:controller --resource FormController
In my web.php I added this :
Route::resource('form','FormController');
my view has a simple form in it :
<form action="/form" method="POST" >
<input type="text" name="cih">
<input type="submit">
</form>
I open my view with the create method :
public function create()
{
return view('contact');
}
I want that when I submit my form I get my data, so I use my 'store' method :
public function store(Request $request)
{
return $request->all();
}
But instead of getting it, I get 419 message, and my session has expired etc ..
I followed a course and that what the teacher was doing I believe nothing more, so I would appreciate any help, I need it.
Thank you
You need to include the CSRF token while submitting a form since the 'VerifyCsrfToken' middleware is enabled by default for the web routes in App/Http/Kernal.php.
<form action="/form" method="POST" >
#csrf
<input type="text" name="cih">
<input type="submit">
</form>
And, Welcome to Laravel!
I will get MethodNotAllowedHttpException when submitting a form in laravel
Html file
<form method="POST" action="/cards/{{$card->id}}/notes">
<input name="_token" type="hidden" value="{{ csrf_token() }}"/>
<textarea name="body" class="form-control"></textarea>
<button type="submit">Add Note</button>
</form>
routes.php
Route::post('cards/{card}/notes','NotesController#store');
NotesController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
class NotesController extends Controller
{
public function store()
{
return request()->all();
}
}
Make sure you don't have a route, say a Route::post with a parameter that lies in front of the route you are trying to hit.
For example:
Route::post('{something}', 'SomethingController#index');
Route::post('cards/{card}/notes', 'NotesController#store');
In this case, no matter what you try to send to the cards route, it will always hit the something route because {something} is intercepting cards as a valid parameter and triggers the SomethingController.
Put the something route below the cards route and it should work.
MethodNotAllowedHttpException is thrown when no matching route (method and URI) was found, but a route with a matching URI but not matching method was found.
In your case, I guess the issue is because URI parameters differ between the route and the controller.
Here are two alternatives you can try:
Remove the parameter from your route:
Route::post('cards/notes','NotesController#store');
Add the parameter to your controller:
public function store($card)
{
return request()->all();
}
I have tried to solve this error in lumen and it took me quite a lot of time to figure out the problem.
The problem is with laravel itself.
Sometimes if you have another route like GET device/{variable}, laravel stops in this first route...
So what you need to do is change the route POST device to POST device/add
This link helped me a lot
In reference to this stockoverflow question
I created a new request with php artisan make:request ApplicationFormRequest
public function rules() {
return ['first_name' => 'required']
}
I also have a controller as such,
public function store(ApplicationFormRequest $request){
//empty
}
I have seen an example on stackoverflow with
return Redirect::to('/')->withInput();
they seem to put their validation together with the controller, but I am not sure how to go about it this way.
Where would I put that? How do I retrieve old input even with validation fail?
EDIT you see my controller is empty, it validate automatically with the rule i set at ApplicationFormRequest. when it failed it automatically redirect to the view where the input is submitted with error
#foreach ($errors->all() as $error)
<li class="alert label">{{$error}}</li>
#endforeach
but I am unable to fill the input with the input user just submitted, I try to do
<input type="text" value="{{ old('first_name') }}" \>
but this give me error Use of undefined constant
In Laravel 5.2, if the view forms are not being populated with old data sent back from a custom Request class, do the following:
1) Place all routes related to the request in the route group, which should be included in 5.2
Route::group(['middleware' => ['web']], function () {
// routes here
});
2) Run php artisan key:generate
EDIT: This fix may not be applicable for versions other than 5.2.
Credits:
Laravel - Session store not set on request
No supported encrypter found. The cipher and / or key length are invalid.
Another relevant post
as the error say use of undefined constant. Your errors variable is not in the scope of view. check what you are doing wrong.
use Docs for further reading.
You can do this by checking if a value is available in the POST or GET array first. If it is available in the POST or GET array, then echo it in the value attribute of the input.
Your input field would look something like this:
<input type="text" name="first_name" value="if (Input::has('first_name')){ #echo Input::get('first_name');}" \>
I've looked around to see if I can find this specific problem, but have been unsuccessful so far.
The problem is pretty simple. I'm using an artisan-generated UsersController to handle RESTful communication on the /users directory. GET works just fine, but whenever I POST a form to /users, instead of executing the store() method properly like it should, it throws the MethodNotAllowedHttpException error. When I made a new handler postNew(), and POST to users/new, it works just fine. I could just use that, but I would really like to figure out what the problem is so I can use the standard RESTful method.
Additionally, I'm not using Laravel's form generator because I intend to cache every page for speed, and don't want to generate a unique id for every form I send. I saw on another post that this might be causing problems, but couldn't figure out a way to integrate it into a solution.
<form id="signup-form" method="POST" action="users">
<label>First Name:</label>
<input type="text" name="firstName">
<label>Last Name:</label>
<input type="text" name="lastName">
<input type="submit" value="Sign Up Free!">
</form>
That's my code.
controller:make will only create a resource controller, it will not define its route(s).
Since you mention that you created a new controller method postNew(), and it works when you send a POST request to users/new, I will assume that you have created a RESTful controller route and not a resource route.
RESTful controller route (not compatible with controller:make):
Route::controller('users', 'UsersController');
Resource controller route (compatible with controller:make):
Route::resource('users', 'UsersController');
The differences between these two controller types are outlined on the Controllers docs page: RESTfull vs. Resource.
In a case where the form action is set to something like:
action="<?php echo JRoute::_('index.php?option=com_test&layout=edit&id='.(int) $this->item->id); ?>"
and the form contains and hidden input:
<input type="hidden" name="task" value="testctrl.save" />
How does joomla route to the controller method?
I would understand if it had the task in the form action, but I can't see how it picks up the task from the hidden input in order to route to the appropriate method in the testctrl controller method
It's not that complicated. In your com_mycom directory there is a file called mycom.php. In it you have some lines that look like this:
$controller = JControllerLegacy::getInstance('Contact');
$controller->execute(JFactory::getApplication()->input->get('task'));
$controller->redirect();
See an example here:
https://github.com/joomla/joomla-cms/blob/staging/components/com_contact/contact.php#L15
So that's what takes the task and instantiates an instance of that controller object, and pulls the task from the hidden form input value that you pointed out. It passes the task to the controller from there.
The controller receives the request here:
https://github.com/joomla/joomla-cms/blob/staging/components/com_contact/controller.php#L19
You might be asking "why don't I see it receiving the task that the component file sends it?". Well that's because the controller for this component is a child-class of the JControllerLegacy class:
https://github.com/joomla/joomla-cms/blob/staging/libraries/legacy/controller/legacy.php#L701
public function execute($task)
{ ... }
This function is the execute function which receives the task from the component. This is the parent class of your controller task. Hopefully this all makes sense!
When you set the controller name explicitly with hidden fields
<input type="hidden" name="task" value="testctrl.save" />
or
<input type="hidden" name="controller" value="testctrl" />
<input type="hidden" name="task" value="save" />
or even not specifying the controller with task , just used it with view name.
All the cases your component file like com_test have a file with test.php
it includes Joomla library files.
jimport('joomla.application.component.controller');
when you check the library file it have two function for getting related controller and models.
createFileName() and getInstance() in libraries/joomla/application/component/controller.php
These two function do the task.
The above files are applicable only for Joomla 1.5 to Joomla 2.x
Edit
For Joomla3.x
In Joomla 3. x The file structure little bit changed.
Instead of jimport('joomla.application.component.controller'); Joomla 3.x uses
$controller = JControllerLegacy::getInstance('Content');
This will call the JControllerLegacy class in libraries\legacy\controller\legacy.php
you can find the same functions createFileName() ,getInstance() on the above path.
Hope its helps..