0

I have quite a few resource controllers in a Laravel project and I usually do something like this:

/**
 * Update the specified resource in storage.
 *
 * @param  \Illuminate\Http\Request $request
 * @param  int $id
 * @return \Illuminate\Http\Response
 */
public function update(Request $request, $id)
{
    $chat = Chat::find($id);
    $chat->customer_id = $request->get('customer_id');
    $chat->content = $request->get('content');
    $chat->save();
    return redirect('/chat');
}

As routes sometimes change, I moved on to use another redirect like so:

return redirect()->action('ChatController@index');

Which works better for me, because now the routes can be whatever they want, it still works fine. Yet there is another "problem" and that is the controller's name. If I rename ChatController to CustomerChatController this action does need a rework, which is a bit annoying.

My question: Is there a trick out of the box to target always the "self" controller. Something like

return redirect()->action(self::class . '@index');

So any renaming of controllers does not matter at least within the controller?

Edit: Yeah I've seen named routes before and yet this not a duplicate post. Named routes are a bit of a mess for ressource controllers. As the doc states:

Route::resource('photo', 'PhotoController', ['names' => [
    'create' => 'photo.build'
]]);

One can name the routes there as well but I end up with several 100s of names and I really don't care about any of those names (speaking of resource controllers, the single ones I do give a name).

Edit2: So you are telling me, instead of 1 of say ~150 routes like this

Route::resource('chat', 'ChatController');

I should add this into the routes/web.php:

Route::resource('chat', 'ChatController',
    ['names' => [
        'create' => 'chat.create',
        'update' => 'chat.update',
        'store' => 'chat.store',
        'destroy' => 'chat.destroy',
        'edit' => 'chat.edit',
        'index' => 'chat.index',
        'show' => 'chat.show'
    ]]);

Then use those names. And this is why it's a duplicate post? That seems stupid to me. Resource controllers are cool because they don't mess up the routes table with repetitive behavior and with your solution of named routes I end up with 7 lines instead of one resource controller route.

Solution: Seems as tho I was pretty close. This one works fine:

return redirect()->action(class_basename(self::class) . '@index');

I found a hint for this here:

Get Laravel 5 controller name in view

Final solution: To have some auto code completion, which by the way I never get on any named routes like this return redirect()->route('chat.create'); , I added the basic routes to the Controller.

class Controller extends BaseController
{
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;

    protected static function routeCustom($name)
    {
        $action = app('request')->route()->getAction();
        $controller = class_basename($action['controller']);
        list($controller, $action) = explode('@', $controller);

        return $controller . '@' . $name;
    }

    protected static function routeIndex()
    {
        return self::routeCustom('index');
    }

    protected static function routeStore()
    {
        return self::routeCustom('store');
    }

    protected static function routeEdit()
    {
        return self::routeCustom('edit');
    }

    protected static function routeCreate()
    {
        return self::routeCustom('create');
    }

    protected static function routeShow()
    {
        return self::routeCustom('show');
    }

    protected static function routeUpdate()
    {
        return self::routeCustom('update');
    }

    protected static function routeDestroy()
    {
        return self::routeCustom('destroy');
    }
}

So I can access them to redirect within the same controller like so:

return redirect()->action(self::routeIndex());

Which redirects to WhateverController@index

andi79h
  • 1,087
  • 1
  • 12
  • 18
  • I have an answer for this problem [here](https://stackoverflow.com/a/46941686/4881811) ;) – Maraboc Dec 13 '17 at 09:15
  • As @Maraboc's solution states using named routes seems to be the most elegant way to do this. – apokryfos Dec 13 '17 at 09:18
  • Please next time search before posting a question ... – Gothiquo Dec 13 '17 at 09:19
  • Yeah I've seen named routes and yet this a bit of a mess for ressource controllers. As the doc states: ```Route::resource('photo', 'PhotoController', ['names' => [ 'create' => 'photo.build' ]]);``` One can name the routes there as well but I end up with several 100s of names and I really don't care about any of those names (speaking of resource controllers, the single ones I do give a name). – andi79h Dec 13 '17 at 09:24
  • For the resource routes they have a name by default for example `Route::resource('photo', 'PhotoController')` you have photo.create as name for the create method photo.index for the index method ... ! – Maraboc Dec 13 '17 at 10:35
  • Yeah, even then I need to add >100 names and the function to access it has no auto code completion. This is pretty ok to access different controllers, yet I was searching for a solution within the own controller. That's why it is **NOT** a duplicate. – andi79h Dec 13 '17 at 11:25
  • 1
    So, if you're stuck in duplicate purgatory, it often makes more sense to ask a new question, adding the details that distinguish it as a unique question. Further, NEVER answer the question in the question. That's asking for it to be deleted (and you lose points for that). – theMayer Dec 13 '17 at 18:02
  • @theMayer: Thanks for claryfing this. I'm kinds new to the community and try to offer as much info as I can. Some rules are pretty strange to me tho :D – andi79h Dec 13 '17 at 18:27
  • The rules are formulated so that users searching in google have the highest probability of finding the answer they need on the first try. Sometimes that makes it painful for askers, but it is the way it is for a reason – theMayer Dec 13 '17 at 18:36

1 Answers1

-1

I think better solution would be to give names to routes and use redirect()->route('routeName'); So your controller name won't depend on redirect.

You can read more about this here: https://laravel.com/docs/5.5/routing

Tony Vincent
  • 13,354
  • 7
  • 49
  • 68
Ivan Jelev
  • 115
  • 3
  • I agree with you – Gothiquo Dec 13 '17 at 09:18
  • Nah, I simply don't want to track >100 random names for my controllers and live without code completion on the named routes. To me, that feels like PHP4 and tons of includes, the world before autoloading. I really don't care about the route. It can be whatever the controller's name is. – andi79h Dec 13 '17 at 11:20