Starting off with a bit of background information, i have 3 models - Course, Pathway, Module.
Course HAS-MANY Pathway
Pathway HAS-MANY Module
Course HAS-MANY-THROUGH Module (through Pathway)
I have set up routes for creating Course, Pathway and Module. However, when I try to save the newly created model instance, it calls the wrong route method - does not even hit the store method of the relevant Controller
I understand that the order of the routes is important. I tried changing them around but it still does not work as intended.
Here's what I have so far
:
// modules
Route::get('/courses/{course}/edit/pathways/{pathway}/modules/create', [App\Http\Controllers\ModulesController::class, 'create'])->name('createModule');
Route::post('/courses/{course}/edit/pathways/{pathway}/modules', [App\Http\Controllers\ModulesController::class, 'store'])->name('storeModule');
// Pathways
Route::get('/courses/{course}/edit/pathways/create', [App\Http\Controllers\PathwaysController::class, 'create'])->name('createPathway');
Route::get('/courses/{course}/pathways/{pathway}/edit', [App\Http\Controllers\PathwaysController::class, 'edit'])->name('editPathway');
Route::delete('/courses/{course}/pathways/{pathway}', [App\Http\Controllers\PathwayController::class, 'destroy'])->name('destroyPathway');
Route::post('/courses/{course}/edit/pathways', [App\Http\Controllers\PathwaysController::class, 'store'])->name('storePathway');
// VQs/Qualifications
Route::resource('courses', App\Http\Controllers\CourseController::class, [
'names' => [
'index' => 'allCourses',
'create' => 'createCourse',
'store' => 'storeCourse',
'show' => 'showCourse',
'edit' => 'editCourse',
'update' => 'updateCourse',
'destroy' => 'destroyCourse',
]
]);
The problem is that when I try to store a Pathway or Module, it hits the Route::post('/courses/{course}') route.
I tried changing around the order of the routes, but none of that worked. I've also made sure that the create forms action is of the right Url Route. its all still the same.
I also can't tell which controller method is being called. Tried doing a dd() on CourseController#create, PathwaysController#create, ModulesController#create but none of them get hit.
Any help as to why this is happening will be greetly appreciated
Edit
here are some of my routes:
Since your URLs are quite similar.
How about refactoring your URL.
Also, writing a cleaner code would save you lots of headaches.
At the top:
<?php
use App\Http\Controllers\ModulesController;
use App\Http\Controllers\PathwaysController;
Route::name('modules.')->prefix('modules/courses')->group(function()
Route::get(
'{course}/edit/pathways/{pathway}/create', //e.g: modules/courses/engligh/edit/pathways/languages/create
[ModulesController::class, 'create']
)->name('create'); //modules.create
Route::post(
'{course}/edit/pathways/{pathway}',
[App\Http\Controllers\ModulesController::class, 'store']
)->name('store'); //modules.store
});
Route::name('courses.')->prefix('courses')->group(function()
Route::get(
'{course}/edit/pathways/create', //e.g: courses/english/edit/pathways/create
[PathwaysController::class, 'create']
)->name('create'); //courses.create
Route::get(
'{course}/pathways/{pathway}/edit',
[App\Http\Controllers\PathwaysController::class, 'edit']
)->name('edit');//courses.edit
Route::delete(
'{course}/pathways/{pathway}',
[App\Http\Controllers\PathwayController::class, 'destroy']
)->name('destroy');//courses.destroy
Route::post(
'{course}/edit/pathways',
[App\Http\Controllers\PathwaysController::class, 'store']
)->name('store');//courses.store
});
Run php artisan route:list to view your routes
Fixed it. Turns out there wasn't a problem with my routes at all.
The problem was that I had vertical navs and tab-panes on that page, and most of them had a form in them. I had not closed the form in one of the tab-panes and so this form was getting submitted to the action of the form above in that page.
i.e. Make sure to close forms using:
{{ Form::close() }}
Related
I am pretty new to Laravel, I am so confused on how to start this. but basically I have a switch statement with different display mode cases and what I am trying to do is to connect routing with blade. How do I display $mycontent in blade based on cases like these ? Thanks
switch(MyPage::$some_display_mode) {
case 'normal':
$mycontent //this is what I want to display in blade
case 'ajax':
case 'other'
}
I want to connect these cases normal,ajax ,other etc with with different MyPages that I have so that I can display my blade files something like this
<html>
#yield('content)
</html>
#section('content')
whatever comes from the pages
#endsection
You can use route groups and do something similar to this:
Route::group( [ 'prefix' => 'AJAX', 'namespace' => 'AJAX' ], function() {
Route::get( '/something', 'ajaxController#doSomething' );
});
There is multiple ways to group routes shown here:
laravel grouped routing
Then handle returning the view in the controller and the use template-inheritance as explaned here:
laravel template-inheritance
This way will allow you to group and keep your routes organized
up until this point I have essentially been using resource routing. One of my routes is for projects. If I create a project and then SHOW it, I see a URL in the form of
myUrl/projects/1
On the show page for a project, I want to be able to add a document. I have set up the relationships so a project can have one document and a document belongs to a project. I then set up the following route to handle the saving of the documents data
Route::post('projects/{id}/docOne', 'DocOneController#store');
So I add an a form in projects/show.blade.php, which opens like so
{!!
Form::model(new App\DocOne, [
'class'=>'form-horizontal',
'route' => ['docOne.store']
])
!!}
I then have my form fields and a save data button. Because of this new form within my projects show page, when I now show a project, it complains that the route for this new form is not defined.
How can I get this route to work within the projects show page?
Thanks
First of all you need to define a route name to your route, if you want to call it by his name.
So your route would be like:
Route::post('projects/{id}/docOne', [ //you need an array to set a route name
'as' => 'docOne.store', //here define the route name
'uses' => 'DocOneController#store' //here the callback
]);
Second you need to change your laravel form to use your route name and set the id
{!! Form::model(new App\DocOne, [
'route' => ['docOne.store', $project], //if you have setted the id variable like $id blade it gonna retturn it automatically only by passing the object, else, you can set $project->id
'method' => 'POST']
) !!}
EDIT:
You can't get an instance of a model on your view.
So the part:
{!! Form::model(new App\DocOne,
gonna fails every time you trye, also, the form:model needs an instance of a class that should have your vars filled with the info that the inputs should have (when you edit it).
You have two solutions:
If it's a new Doc and never before exist on your dataBase
I recomend to change your
Form::model
to:
Form::open
if it's a Doc thath already exist on your DB, like an edit, so in your controller you need to pass your existing Docas $docand remplace the: {!! Form::model(new App\DocOne, to:
{!! Form::model($doc,
and it works.
Form model was created to fill the input values with the data existing in your object instance, like when you edit someting.
So you need to have a correct instance.
Another think it's the MVC scope, a view shouldn't have acces to models, except if are passed by the controller.
Ok that's all.
So I've started using Laravel and I found it very easy and now I'm creating my own restful services. My problem is I don't know if I am doing the href link correct, but yes it is working. Here is the code:
Add user
And in my controller I just render the blade:
public function create()
{
return view('accounts.create');
}
So if I click the link Add user, it will redirect me to localhost:8080/accounts/create which is working well. My question is, is there a better way of doing this? Like if ever I changed any in my routes file, I will not change anymore the href link?
Ideally, you will name the route in your routes file.
Something like,
Route::get('accounts/create', [as => 'createAccount', 'uses' => 'AccountsController#create']);
You will use it as follows
Add user
in your view.
This way, even if you change the url (accounts/create), or the action name (create), you will not have to change it in the view. Allows your view to be independent.
What you can do is give your route a name using the as key in the array in the second argument of your route:
Route::get('accounts/create', [
'as' => 'accounts.create',
'uses' => 'AccountController#create'
]);
Then you can refer to this route in your application by it's name and it'll go to the same place even if you happen to change the URL. For an anchor tag you can do the following:
{{ URL::route('accounts.create') }}
If you're using a resource controller there will be predefined routes which you can see here under Actions Handled By Resource Controller: http://laravel.com/docs/5.1/controllers#restful-resource-controllers
You can always get a quick overview of your available routes and their names by running php artisan route:list
http://laravel.com/docs/4.2/routing#named-routes
Example:
Route::get('accounts/create', array('as' => 'signup', 'uses' => 'UserController#create'));
Add user
This route is named as "signup" and you can change the url anytime as:
Route::get('accounts/signup', array('as' => 'signup', 'uses' => 'UserController#create'));
Yes, you can use the action() helper to call a method inside a controller and generate the route to it automatically on demand.
So let's consider you have a controller called FrontendController.php and a method called showFrontend( $section), and assuming that you have a route that matches this controller and method (let's say "frontend/show/{$section}", you can call:
action('FrontendController#showFrontend', array( 'index' ) )
That will return:
frontend/show/index
So basically it looks for the route associated to that method/controller. You can combine this with other helpers to create a whole URL.
NOTE: Consider the namespaces, in case that you have different folder for controllers, nested resources, etc.
I hope it helps!
Form actions always confused me as it seemed very simple just to specify the controller however, every time I use it I always get Route [Controller#method] not defined. So I always go and manually make the route then use a url for my forms.
I currently have a route set up as Route::controller('handle/events', 'EventsController') and I'm trying to call the method postAdd from a form like:
{{ Form::open(['action' => 'EventsController#postAdd']) }}
instead of using
['url' => 'handle/events/add'] which is perfectly acceptable given that this is a RESTful route.
When I use the action, Laravel throws Route [EventsController#postAdd] not defined.. The method postAdd in the EventsController also accepts a parameter which I would like to pass in the form.
In the controller, the method is
public function postAdd($staff = false) {
var_dump($staff); // Always false
}
and once again I thought it would be as simple as:
{{ Form::open(['url' => 'handle/events/add'], true) }} however it did not change the value of $staff.
Recap
I would like to change my forms to point to controller methods rather than urls.
I would like to pass a parameter with my forms.
First Problem can be solved by naming your routes.
For example: Route::post('handle/events/add',['as' => 'handle.event.add', 'uses' => 'EventsController#addMethod']);
Then in your form you can do something like this
{{ Form::open(array('route' => 'handle.event.add', 'method' =>'POST'))}}
Now your form will use EventsController#addMethod
Docs named routes
If you want to pass a parameter to the controller method you can define it in your route
Route::get('handle/{event}',['as' => 'handle.event.add', 'uses' => 'EventsController#addMethod'])
Now your addMethod expects a paramter.
I'm creating an authorization system in my Laravel 4 project. I am trying to use the auth "before" filter.
In my routes.php file, I have:
Route::get('viewer', array('before' => 'auth', function() {
return View::make('lead_viewer');
}));
Route::get('login', 'LoginController');
The before filter calls this line in the filters.php file:
Route::filter('auth', function()
{
if (Auth::guest()) return Redirect::route('login');
});
I can manually navigate to my login route. But the auth system isn't letting this happen. I've run composer dump-autoload a couple of times, so that isn't the problem. What am I doing, since I can actually load the login page if I do it manually?
I figure it out. Laravel is looking for a named route: I had to do this:
Route::get('login', array('as' => 'login', function() {
return View::make('login');
}));
An interesting, not very intuitive approach in Laravel. But there must be a reason Taylor did this that I'm not seeing.
To do what you were trying to do in your initial approach you could have just done:
Route::filter('auth', function()
{
if (Auth::guest()) return Redirect::to('/login');
});
and it would have worked just fine.
If you want to use named routes then you do what you posted in your answer to your own question. Essentially...more than one way to skin a cat.
Hope that helps
I know you've probably solved this by now but after stumbling across your post while trying to solve a similar problem, I wanted to share my thoughts...
Laravel is NOT looking for a named route for the guest method, it is expecting a path.
Your example works because because the named route and the path are the same i.e. "login". Try changing your URL to something other than 'login' and watch it fail.
If you want to use a named route you should use the route helper method as so...
if (Auth::guest()) return Redirect::guest( route('login') )
Hope that helps someone.