Pez Cuckow
Pez Cuckow

Reputation: 14412

Laravel URL Generation Not Including Parameters

I'm seeing an issue with Laravel 4 when I have two routes pointing to the same action, one within a group and one just "loose" in the routes.php file.

<?php     

// Routes.php
Route::group(array('domain' => '{subdomain}.domain.com'), function()
{
        Route::get('profile/{id}/{name}', 'ProfileController@index');
});

Route::get('profile/{id}/{name}', 'ProfileController@index');

// Template.blade.php
<a href="{{ URL::action('ProfileController@index', array(123, 'JimSmith')) }}">Jim Smith</a>

The template links to: currentsubdomain.domain.com/profile/%7Bid%7D/%7Bname%7D instead of the expected behaviour of swapping the ID and name for 123 and JimSmith respectively.

If I comment out, the first route (the one within the group), the code works as expected. Why does adding this additional route break the URL generation? Is there a way to work around this? Am I missing something obvious?

P.s. For those wondering why I need this route in two places it's so I can optionally generate the url with the subdomain using URL::action('ProfileController@index' array('subdomain' => 'james', 'id' => 123, 'name' => 'JimSmith');

Upvotes: 3

Views: 2089

Answers (1)

ollieread
ollieread

Reputation: 6143

The problem is that you don't have names/aliases for the routes so it's defaulting to the first one it comes across.

Consider this an alternate route structure:

Route::group(array('domain' => '{subdomain}.domain.com'), function() {
    Route::get('profile/{id}/{name}', [
        'as' => 'tenant.profile.index',
        'uses' => 'ProfileController@index'
    ]);
});

Route::get('profile/{id}/{name}', [
    'as' => 'profile.index',
    'uses' => 'ProfileController@index'
]);

Now that you have these routes named, you can do:

{{ URL::route('profile.index', [123, 'jSmith']) }}

Or alternatively:

{{ URL::route('tenant.profile.index', ['subdomain', 123, 'jSmith']) }}

As just an added extra, you could only have this route defined once, then in all the controller methods you'd have something like:

public function index($subdomain = null, $id, $name) { }

Then you can just simply pass www through as the subdomain and have some code somewhere that discounts the www.domain.com domain from certain actions.

Multi-tenancy (if that is indeed what you're after) isn't easy and straight forward but there are some methods used to tackle certain parts. I'm actually planning on writing a tutorial regarding it, but for now I hope this helps somewhat.

Upvotes: 3

Related Questions