How to call method dynamically on routes on Laravel? - laravel

I'm a newbie with this and I need some help.
I'm developing some kind of music library and let's say I don't want to make a route for each artist so I have made this one:
Route::get('/{artist_name}', 'Artist_controller#{artist_name}');
I get the value of {artist_name} from my view and the route works, for instance, the artist_name may be John and the url generated is localhost:8000/John. But when it comes to look for the class in the controller it doesn't work. I have a class named John in my controller, but I keep getting this error when I try to access:
BadMethodCallException
Method [{artist_name}] does not exist.
So I guess the route isn't taking the value of {artist_name}. What I intend is the route to be processed like:
Route::get('/John', 'Artist_controller#John');
But as I said, I don't want to create a specific route for an artist.
I'd appreciate any kind of help. Thank You

There is no need to create a dynamic method for each artist. You could have one generic method in your controller that handles retrieving the proper artist information from the database and pass it to the view.
routes file:
Route::get('artists/{artist_id}', 'ArtistsController#show');
ArtistsController.php
class ArtistsController extends Controller
{
public function show($artist_id)
{
$artist = Artists::find($artist_id);
return view('artists.show', ['artist' => $artist]);
}
}
So if the user hits the following URL http://localhost/artists/4 the artist id of 4 will be passed to the show method and it will dynamically looks for an artist with that ID and pass an object of artist to your view.
Of course you are not limited to IDs in your URLs. You can use the name if it was unique and your code will be as the following.
routes file:
Route::get('artists/{artist_name}', 'ArtistsController#show');
ArtistsController.php
class ArtistsController extends Controller
{
public function show($artist_name)
{
$artist = Artist::where('name', $artist_name);
return view('artists.show', ['artist' => $artist]);
}
}
I suggest you read this documentation for more information about routing.

You can not have dynamic method (controller action) in a controller class. Instead you should define a method and pass the route parameter to that action.
In your route (web.php) file:
Route::get('/{artist_name}', 'ArtistController#artist');
then in ArtistController.php:
public function artist ($artist_name) {
// do stuff based on $artist_name
}
To get more info read these 2 documentation pages. Controller and Routing.

Related

Laravel route difference between {id} vs {tag}

I am new in Laravel pardon me if question is silly. I have seen a doc where they used
For get request
Route::get("tags/{id}","TagsController#show");
For put request
Route::put("tags/{tag}","TagsController#update");
What is the difference and benefit between this ? I understood 1st one, confusion on put route.
There’s no real difference as it’s just a parameter name, but you’d need some way to differential parameters if you had more than one in a route, i.e. a nested resource controller:
Route::get('articles/{article}/comments/{comment}', 'ArticleCommentController#show');
Obviously you couldn’t use just {id} for both the article and comment parameters. For this reason, it’s best to use the “slug” version of a model for a parameter name, even if there’s just one in your route:
Route::get('articles/{article}', 'ArticleController#show');
You can also use route model binding. If you add a type-hint to your controller action for the parameter name, Laravel will attempt to look up an instance of the given class with the primary key in the URL.
Given the route in the second code example, if you had a controller that looked like this…
class ArticleController extends Controller
{
public function show(Article $article)
{
//
}
}
…and you requested /articles/123, then Laravel would attempt to look for an Article instance with the primary key of 123.
Route model binding is great as it removes a lot of find / findOrFail method calls in your controller. In most instances, you can reduce your controller actions to be one-liners:
class ArticleController extends Controller
{
public function show(Article $article)
{
return view('article.show', compact('article'));
}
}
Generally there's no practical difference unless you define a custom binding for a route parameter. Typically these bindings are defined in RouteServiceProvider as shown in the example in the docs
public function boot()
{
parent::boot();
Route::model('tag', App\Tag::class);
}
When you bind tag this way then your controller action can use the variable via model resultion:
public function update(Tag $tag) {
// $tag is resolved based on the identifier passed in the url
}
Usually models are automatically bound so doing it manually doesn't really need to be done however you can customise resolution logic if you do it manually
Normal way
Route::get("tags/{id}","TagsController#show");
function($id)
{
$tag = Tag::find($id);
dd($tag); // tag
}
With route model bindings
Route::put("tags/{tag}","TagsController#update");
function(Tag $tag) // Tag model binding
{
dd($tag); // tags
}
ref link https://laravel.com/docs/5.8/routing#implicit-binding
It's just a convention. You can call it all you want. Usually, and {id} refers to the id in your table. A tag, or similarly, a slug, is a string value. A tag could be 'entertainment' for video categories, while 'my-trip-to-spain' is a slug for the description of a video.
You have to chose the words what you are comfortable with. The value will be used to find in your database what record is needed to show the correct request in the view. Likewise you can use video/view/{id}/{slug} or any combination thereof.
Just make sure your URLs don't get too long. Because search engines won't show your website nicely in search results if you do. Find the balance between the unambiguous (for your database) and logic (for your visitors).
Check this out: Route model bindings
Use id, Laravel will get the id from route, and it will be the tag's id, it is integer.
function show($id) {
$tag = Tag::find($id);
}
Use tag, Laravel automatically resolves Eloquent models defined in routes or controller actions whose type-hinted variable names match a route segment name.
In URL, your tag parameter is integer, however in your controller action $tag will be a model object:
function action(Tag $tag) {
$tag->name;
}
So you don't need to get the $tag by eloquent in your controller action. You just need to specify it is From model Tag $tag
It will do it automatically.

laravel 5.8 edit function with model instance

public function edit(EduLevel $eduLevel)
{
dd($eduLevel->name);
return view('adm.edulevel.edit',compact('eduLevel'));
}
Route::resource('edulevel','EduLevelController'); //web.php
with resource route
how to get eduLevel to view with model instance laravel. in previous i call with parme parameter id and use find() method to get data..
from this sample - https://itsolutionstuff.com/post/laravel-58-crud-create-read-update-delete-tutorial-for-beginnersexample.html
I don't understand the question but I will just guess that you have a route that accepts a parameter that you you expect it to be the model inside your function.
You need to create a route like this one:
Route::get('/edit/{eduLevel}', 'SomeController#edit');
Notice the same name for the variable, this is important otherwise you will get only the id, slug or whatever.
Make sure your path name also have the same name for route segment name.
so your route path should be like this.
Route::get('/edit/{variablename}', 'ControllerName#edit');
your controller function logic should be like this.
public function edit(EduLevel $variablename)
{
return view('adm.edulevel.edit',compact('variablename'));
}
So make sure your variable name in route and in controller function
should be same.
For more information, you can read Route Model Binding in laravel
I am having the same problem (almost).
I wanted to call a controller method in the view. So I should pass the model from controller to view.
How to pass model from controller to view?
I found this [Laravel 5 call a model function in a blade view but using ->withModel($model); to pass the model from controller to view and {{$model->someFunction()}} to call the method in the view is not working.
Any advice please?

Create route for every controller of index method in Laravel

I'm developing a school management system in laravel. I have many controllers like
controller staff in method index
class controllerstaff extends controller {
public function index{
//here process of staff data
}
}
//this controller have `Route::get('/', 'controllerstaff#index');
and other controller
class controllerstudent extends controller {
public function index{
//here process of student data
}
}
//this controller have Route::get('/', 'controllerstudent#index');
As above does not work properly.
Any one can tell me how to create route for every controller of index method. If we crate many route file then how operate it and how access in controller and form action
You cannot create same urls for each route. For each route you need to have different url, for example:
Route::get('/staff', 'controllerstaff#index');
Route::get('/students', 'controllerstudent#index');
You should also name your controllers rather StudentController and not controllerstudent. You might also consider looking at Routing documentation before creating code - I believe it might be the right way ;)

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'));
}
}

Code Igniter: Creating a blog cms: display a blog post that is given in the URL

URL: www.blog.com/posts/category/post-title
How do I create a controller, that accepts the two parts of the URL "category" and "post-title" and echoes out the post?
Thank you a lot.
Timo
In CodeIgniter the URL is mapped as domain/Controller/Method/params, so following URL
www.blog.com/posts/category/post-title
will be mapped as posts is the controller, category as method name and rest are parameters. So, You need to create a controller like this:
// posts.php
class Posts extends CI_Controller {
public function show($category, $title)
{
// ...
}
}
Then the URL could be www.blog.com/posts/show/some-category/post-title and you can retrieve the some-category and post-title as parameters in you show method. For more information, check Controllers on CI User Guide.

Resources