Its Laravel 5.
When the route.php contains this:
Route::get('/foo', function () {
return 'Hello World';
});
then the page shows with the text "Hello World".
However, as soon as I add this new line in route.php:
Route::get('/foo2', 'IndexController');
then the page show this error:
UnexpectedValueException in Route.php line 567: Invalid route action: [App\Http\Controllers\IndexController]
I previously created a controller with artisan which now looks like this:
class IndexController extends Controller
{
public function index()
{
echo 'test';
}
}
what am I doing wrong?
You have to specify wich method will be executed:
Route::get('/foo2', 'IndexController#index');
If you are using get method of Route. Normally first argument provided should be the url and second argument should be the method (there are other ways argument could be passed)
Route::get('/foo2', 'IndexController#index');
If you want to resourceful route . Normally first argument should be the resource name and the second argument should be RESTful controller name. (there are other ways argument could be passed).Example: photo is the resource name and PhotoController is the controller name.
Route::resource('photo', 'PhotoController');
in your case it should work this way
Route::resource('/foo2', 'IndexController');
or
Route::get('/foo2', 'IndexController#index');
so when you visit
yoursite.com/foo2
you will be displayed with IndexController index method
See reference more to learn laravel's restful resource controller
reference: https://laravel.com/docs/5.1/controllers#restful-resource-controllers
You need to specify the function inside the controller not just the controller:
Route::get('/foo2', 'IndexController#index');
You have to reference Controller#method as:
Route::get('/myroute', ['uses' => 'MyController#methodName']);
Related
I am trying to get to a page I added to my route but it says "File Not Found".
I have set up a route to the WebsiteController but that didn't work. The index route '/' is working as expected. I tried manually creating the controller and using php artisan to see if there was a difference but it's the same. I also tried change the "post" to a "get", "any", etc.
Routes
<?php
Route::get('/', function () {
return view('welcome');
});
Route::post('/website/{url}', 'WebsiteController#index');
WebsiteController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class WebsiteController extends Controller
{
public function index($url) {
return $url;
}
}
I expected to see what I have put in the URL after 'website/', it simply says "File not found".
You have defined the route to expect a parameter:
Route::post('/website/{url}', 'WebsiteController#index');
Because you wrote website/ as the address, you did not provide the parameter that the route was expecting (url in this case). If your route was:
Route::post('/website', 'WebsiteController#index');
This would have worked, but failed when it got to the controller because the index method was expecting a parameter.
Simple fix: change the route as above, or add the parameter at the end of the url: website/someUrl. Also make sure you are using the right method (post vs get) - if typing in the address bar, remember to use get in your Route method.
I am working on a Laravel 5.5 application. When I use php artisan make:model SomeModel -mr it creates the model, migration and resource controller.
I've been noticed that some methods have by default only one parameter: the model:
public function show(SomeModel $someModel)
{
...
}
If you look into the $someModel variable it has an empty SomeModel object.
I was reading on Laravel Documentation that it looks like the Containers or Facades but I am not sure how to use this. Do you?
Edit 1:
I had my routes defined in routes/web.php as: Route::resource('users', 'UserController');
Now I had to define all the routes manually since automatic binding was not working:
Route::get('users', 'UserController#index');
Route::get('users/create', 'UserController#create');
Route::post('users', 'UserController#store');
Route::get('users/{user}/edit', 'UserController#edit', function(App\User $user) {});
Route::post('users/{user}', 'UserController#update', function(App\User $user) {});
Route::post('users/{user}/delete', 'UserController#destroy', function(App\User $user) {});
So, should I replace every resource controller route to manual routing like this?
The resource controller is expecting you to use route model binding. In your routes file, each route that corresponds to a controller action with an injected model will need to have a matching parameter.
For example:
Route::get('user/{user}', 'UserController#show');
Using the above route, the following controller action would receive a user instances that corresponds to the user ID passed as a URL parameter.
class UserController extends Controller
{
public function show(User $user)
{
...
}
}
The reason you're seeing an empty model now is that Laravel will just pass and fresh model to the controller if it is not bound to a route parameter. In other words, if you forget to bind the model in your routes file automatic injection will just give you a new instance.
Note that if you are using a route resource the resulting routes should already have the correct parameters
Route::resource('users', 'UserController');
You can run php artisan route:list to confirm that your actual routes are correct.
Your problem is your controller is expecting two parameters like below:
public function show($id, User $user)
if you try:
public function show(User $user)
it should work correctly.
In your route you are passing only a single param like:
user/{user}
So if you dd the first param it will display the number 1 but if you pass that
to the model it will return the corresponding user as per what id you pass in the route.
The reason your User model was returning an empty object was because there was no value passed to it.
Also make sure your route placeholder: /{user} matches the variable name in
the controller: public function show(User $user).
Hope this helps.
I too came across with the same problem.
If your model having two or more words, you have to use only small letters like $modeModel as $somemodel.
public function show(SomeModel $somemodel)
{
...
}
I use :
Route::controller('home', 'HomeController');
in my routes to link all routes to my controller.
I have a getIndex() function in my controller that's executed when I go to '/home'.
I have a case where I'd like to route to '/home/slug', but not always.
I tried using getIndex($slug), but it always asks for '/home/index/{slug?}'. I don't want index to appear.
Not possible using implicit controllers, as far as the documentation goes (as it seems to enforce RESTFUL pattern).
But your can create a new route just for that:
Route::get('home/{slug}','HomeController#slugedIndex');
Route::controller('home', 'HomeController');
Edit: as pointed by Steve the controller method must come after the get method so one does not overwrite the other.
Arthur's answer was :
Route::get('home/{slug}','HomeController#slugedIndex');
Route::controller('home', 'HomeController');
Although it doesn't work, because anything written after 'home/' will now go into the first route (and HomeController#slugedIndex).
I found a workaround though. I took out the route in routes.php :
Route::controller('home', 'HomeController');
Then in my HomeController, I used the missingmethod() that's called whenever a method isn't found in the controller.
Here's the missing method :
public function missingMethod($parameters = array())
{
$sSlug = is_string($parameters) ? $parameters : '';
$oObject = Object::where('slug', $sSlug)->first();
if ($oObject) {
// slug code
}
else {
// 404 code
}
}
If I have the next route:
Route::get('/user/{id}', function($id) {
return View::make(users.profile, array('id' => $id));
})->where(array('id' => '[0-9]+'));`
How could I do the same in a Restful controller?
Route::controller('/user', 'UserController');
My UserController:
class UserController extends BaseController {
public function getProfile($id) {
return View::make('users.profile', array('id' => $id));
}
}
Thanks for your attention.
where doesn't appear to work when chained onto a Route::controller call, but you can achieve the same functionality with the Route::pattern declaration. So, for example, this code for a Route::controller (called "implicit routing") would work, limiting id to numeric:
Route::pattern('id', '\d+');
Route::controller('/user/{id}', 'UserController');
Then, in UserController, the getIndex method would be called from a GET request:
class UserController extends BaseController {
public function getIndex($id) {
return View::make('users.profile', array('id' => $id));
}
}
Note, however, that this only works for the index method, i.e. for calls to http:://example.com/user/99. If you want to use other controller methods using "implicit routing", for example http:://example.com/user/profile/99 and the controller method getProfile($id), you need to declare your route without the {id} parameter, like so:
Route::controller('/user', 'UserController');
...in which case, you aren't able to use ->where or Route::pattern to constrain the {id}, since there is no {id} parameter to constrain.
In the end, you're better off going with "explicit routing," as you do at the beginning of your answer, or using RESTful Resource Controllers (see the docs) and specifying your route as:
Route::resource('user', 'UserController');.
If you subscribe to Laracasts, Jeffrey Way has a great, clear tutorial about some of the perils of "implicit routing" here.
To make sure about the methods and URL run the php artisan routes from your terminal so you'll get the list of all routes you have access to with their URL. In this case for the following route and controller you may find a URL like user/profile/10
// Route
Route::controller('/user', 'UserController');
// Controller
class UserController extends BaseController {
public function getProfile($id) {
return View::make('users.profile', array('id' => $id));
}
}
So use http://domain.com/user/profile/10, here 10 will be passed to the $id variable in your profile method. Also remember that, in RESTfull controller each method should be prefixed with the HTTP verb they responds to so in this case this method will respond to a GET request.
In order to do it you want to wrap your Route::controller statements in a group and apply where pattern for the group, since setting it globally might not be accurate for other routes:
Route::group('where' => ['id' => '\d+'], function () {
Route::controller('users', 'UsersController');
// other restful controller definitions with this pattern go here
}
In the Laravel documentation on resource controllers (http://laravel.com/docs/controllers#resource-controllers), there is a section titled "Adding Additional Routes To Resource Controllers".
It says to add a route before the resource route is declared. So, in my route.php file I have this:
Route::get('faq/data');
Route::resource('faq', 'ProductFaqController');
After adding the first line show above, my /faq route no longer works. I receive the following error:
Missing argument 2 for Illuminate\Routing\Router::get(), called in /var/www/html/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php on line 208 and defined
Is the documentation wrong? How can I add an additional route to my resource controller? I would like to add a route to /faq/data that will respond to a GET request.
You are missing the action, what should faq/data do?
Route::get('faq/data', function()
{
return 'Hello World';
});
or to a Controller method
Route::get('faq/data', 'MyController#showHelloWorld');