Laravel - Route::resource vs Route::controller - laravel

I read the docs on the Laravel website, Stack Overflow, and Google but still don't understand the difference between Route::resource and Route::controller.
One of the answers said Route::resource was for crud. However, with Route::controller we can accomplish the same thing as with Route::resource and we can specify only the needed actions.
They appear to be like siblings:
Route::controller('post','PostController');
Route::resource('post','PostController');
How we can choose what to use? What is good practice?

RESTful Resource controller
A RESTful resource controller sets up some default routes for you and even names them.
Route::resource('users', 'UsersController');
Gives you these named routes:
Verb Path Action Route Name
GET /users index users.index
GET /users/create create users.create
POST /users store users.store
GET /users/{user} show users.show
GET /users/{user}/edit edit users.edit
PUT|PATCH /users/{user} update users.update
DELETE /users/{user} destroy users.destroy
And you would set up your controller something like this (actions = methods)
class UsersController extends BaseController {
public function index() {}
public function show($id) {}
public function store() {}
}
You can also choose what actions are included or excluded like this:
Route::resource('users', 'UsersController', [
'only' => ['index', 'show']
]);
Route::resource('monkeys', 'MonkeysController', [
'except' => ['edit', 'create']
]);
API Resource controller
Laravel 5.5 added another method for dealing with routes for resource controllers. API Resource Controller acts exactly like shown above, but does not register create and edit routes. It is meant to be used for ease of mapping routes used in RESTful APIs - where you typically do not have any kind of data located in create nor edit methods.
Route::apiResource('users', 'UsersController');
RESTful Resource Controller documentation
Implicit controller
An Implicit controller is more flexible. You get routed to your controller methods based on the HTTP request type and name. However, you don't have route names defined for you and it will catch all subfolders for the same route.
Route::controller('users', 'UserController');
Would lead you to set up the controller with a sort of RESTful naming scheme:
class UserController extends BaseController {
public function getIndex()
{
// GET request to index
}
public function getShow($id)
{
// get request to 'users/show/{id}'
}
public function postStore()
{
// POST request to 'users/store'
}
}
Implicit Controller documentation
It is good practice to use what you need, as per your preference. I personally don't like the Implicit controllers, because they can be messy, don't provide names and can be confusing when using php artisan routes. I typically use RESTful Resource controllers in combination with explicit routes.

For route controller method we have to define only one route. In get or post method we have to define the route separately.
And the resources method is used to creates multiple routes to handle a variety of Restful actions.
Here the Laravel documentation about this.

i'm using Laravel 8 in my project
and in my route file web.php
i add this route
Route::controller(SitesController::class)->group(function() {
Route::get('index', 'index')->name('index');
}
in the Route::controller group we pass controller name we will use
inside the group we define the route we'll use as below syntax
Route::method-used('prefix in the URL', 'function used in the specified controller ')->name(); if the name not used in your code just delete it

Related

Custom Routes not working - 404 not found

I'm trying to create a custom route. The must be in this format: http://localhost:8000/home-back-to-school but instead I get a 404 not found error. http://localhost:8000/posts/home-back-to-school works, but that's not what I'm trying to get working.
My routes on web.php are defined as: Route::resource('posts',PostsController::class);
I modified the Route Service Provider by adding the code below:
parent::boot();
Route::bind('post',function($slug){
return Post::published()->where('slug',$slug)->first();
});
The published scope is defined in the Post Model file(Post.php) as:
public function scopePublished()
{
return $this->where('published_at','<=',today())->orderBy('published_at', 'desc');
}
I've done previously with laravel 5.x, now struggling with laravel 8.x
Link to the Documentation: Laravel 8 Documentation
You should define a custom route since you don't want to use the resourceful route for this method.
In your web.php
// Keep all your resource routes except the 'show' route since you want to customize it
Route::resource('posts', PostsController::class)->except(['show']);
// Define a custom route for the show controller method
Route::get('{slug}', PostsController::class)->name('posts.show');
In your PostController:
public function show(Post $post)
{
return view('posts.show', compact('post'));
}
In your Post model:
// Tell Laravel your model key isn't the default ID anymore since you want to use the slug
public function getRouteKeyName()
{
return 'slug';
}
You may have to fix your other Post routes to make them work with this change since you are now using $post->slug instead of $post->id as the model key.
Read more about customizing the model key:
https://laravel.com/docs/8.x/routing#customizing-the-default-key-name
You should also remove the code you have in the boot method and use the controller instead.
Finally, make sure your post slug is always unique for obvious reason.
Note:
You may run into problems if your other routes are not related to the Post model.
Imagine if you have a route called example.com/contact-us. Laravel has no way to "guess" if this route should be sent to the PostController or the ContactController. contact-us could be a Post slug or it could be a static route to your contact page. That's why it's generally a good idea to start your urls with the model name. In your case, it would be a good idea for your Post route to start with "/posts/" like this: http://example.com/posts/your-post-slug. Otherwise you may run into all sorts unexpected routing issues.
Don't fight the framework: Always follow best practices and naming conventions when you can.

How call resource controller in Laravel 8.0x

when laravel update, some changes in this update, so how to call resource controller give mi example
controller called like:
first use the controller like:
use App\Http\controllers\controller name;
and then
Route::get('/URL', controller-name::class);
but this way i can't call resource controller.
The route you have defined only works for single-action controllers that implement the __invoke() method.
If you are dealing with resource controllers, you can either use the tuple syntax or Route::resource()
Tuple syntax example:
use App\Http\Controllers\PostController;
Route::get('posts', [PostController::class, 'index']);
Route::post('posts', [PostController::class, 'store']);
Route resource example:
use App\Http\Controllers\PostController;
Route::resource('posts', PostController::class);
References:
https://laravel.com/docs/8.x/controllers#single-action-controllers
https://laravel.com/docs/8.x/controllers#resource-controllers

Crud Generator with Laravel

Since 2 weeks I work in a projet of devlopment of a application. I must creat many CRUD and it may take many times. Now I want to know if I can use a free crud generator laravel.If yes, which generator?
Need your Help please.
Command:
php artisan make:model User -mrc
RESTful Resource controller
A RESTful resource controller sets up some default routes for you and even names them.
Route::resource('users', 'UsersController');
Gives you these named routes:
Verb Path Action Route Name
GET /users index users.index
GET /users/create create users.create
POST /users store users.store
GET /users/{user} show users.show
GET /users/{user}/edit edit users.edit
PUT|PATCH /users/{user} update users.update
DELETE /users/{user} destroy users.destroy
And you would set up your controller something like this (actions = methods)
class UsersController extends BaseController {
public function index() {}
public function show($id) {}
public function store() {}
}
You can also choose what actions are included or excluded like this:
Route::resource('users', 'UsersController', [
'only' => ['index', 'show']
]);
Route::resource('monkeys', 'MonkeysController', [
'except' => ['edit', 'create']
]);
RESTful Resource Controller documentation
Implicit controller
An Implicit controller is more flexible. You get routed to your controller methods based on the HTTP request type and name. However, you don't have route names defined for you and it will catch all subfolders for the same route.
Route::controller('users', 'UserController');
Would lead you to set up the controller with a sort of RESTful naming scheme:
class UserController extends BaseController {
public function getIndex()
{
// GET request to index
}
public function getShow($id)
{
// get request to 'users/show/{id}'
}
public function postStore()
{
// POST request to 'users/store'
}
}
Implicit Controller documentation
It is good practice to use what you need, as per your preference. I personally don't like the Implicit controllers, because they can be messy, don't provide names and can be confusing when using php artisan routes. I typically use RESTful Resource controllers in combination with explicit routes.
Laravel already provides CRUD operation see: laravel.com/docs/5.8/controllers#resource-controllers
Laravel resource routing assigns the typical "CRUD" routes to a controller with a single line of code. For example, you may wish to create a controller that handles all HTTP requests for "photos" stored by your application. Using the make:controller Artisan command, we can quickly create such a controller:
php artisan make:controller PhotoController --resource
[EDIT 1]
Or you can choose for example: Laravel-Backpack/CRUD which comes with an Admin panel and others things like that.
[EDIT 2]
Also you can refer this Laravel blog to choose a generator:
https://laravel-news.com/13-laravel-admin-panel-generators
[EDIT 3]
Again on Laravel Blog you can see that Laravel is constantly evolving a new Artisan command have been added see:
laravel-news.com/laravel-resources-artisan-command

Pass data from routes.php to a controller in Laravel

I am attempting to create a route in Laravel for a dynamic URL to load a particular controller action. I am able to get it to route to a controller using the following code:
Route::get('/something.html', array('uses' => 'MyController#getView'));
What I am having trouble figuring out is how I can pass a variable from this route to the controller. In this case I would like to pass along an id value to the controller action.
Is this possible in Laravel? Is there another way to do this?
You are not giving us enough information, so you need to ask yourself two basic questions: where this information coming from? Can you have access to this information inside your controller without passing it via the routes.php file?
If you are about to produce this information somehow in your ´routes.php´ file:
$information = WhateverService::getInformation();
You cannot pass it here to your controller, because your controller is not really being fired in this file, this is just a list of available routes, wich may or may not be hit at some point. When a route is hit, Laravel will fire the route via another internal service.
But you probably will be able to use the very same line of code in your controller:
class MyController extends BaseController {
function getView()
{
$information = WhateverService::getInformation();
return View::make('myview')->with(compact('information'));
}
}
In MVC, Controllers are meant to receive HTTP requests and produce information via Models (or services or repositores) to pass to your Views, which can produce new web pages.
If this information is something you have in your page and you want to sneak it to your something.html route, use a POST method instead of GET:
Route::post('/something.html', array('uses' => 'MyController#getView'));
And inside your controller receive that information via:
class MyController extends BaseController {
function getView()
{
$information = Input::get('information');
return View::make('myview')->with(compact('information'));
}
}

Laravel 4 view names in controller

I have a controller named CommentsController and 2 views, the first named searchProducts and the second named searchCategories
in the controller i used:
public function getSearchproducts() {
...
}
public function getSearchcategories() {
...
}
.... so the url generated is /comments/searchproducts and /comments/searchcategories...
i want to use urls like '/comments/serach-products' or '/comments/serach_products' is it possible using controllers ??
If your controller action contains multiple words, you may access the
action using "dash" syntax in the URI.
This is mentioned in RESTful Controllers section. So, comments/searchproducts could be used as
comments/search-products
And method would be
public function getSearchProducts() {}
Same for getSearchcategories, url could be comments/search-categories and method
public function getSearchCategories() {}
If you need to change the way your routes are built, you'll have to do them manually:
Route::get('search-products',
array(
'as' => 'search.products',
'uses' => 'CommentsController#getSearchproducts'
)
);
And then, when you do
URL::route('search-products')
It will generate a URI
yoursite/search-products
I'm not really fan of resourceful controllers, I always create them manually, and nor is Phil Sturgeon as you can see in this post.

Resources