1

I need to check that {subcategory} has parent category {category}. How i can get the model of {category} in second binding?

I tried $route->getParameter('category');. Laravel throws FatalErrorException with message "Maximum function nesting level of '100' reached, aborting!".

Route::bind('category', function ($value) {
    $category = Category::where('title', $value)->first();
    if (!$category || $category->parent_id) {
        App::abort(404);
    }
    return $category;
});

Route::bind('subcategory', function ($value, $route) {
    if ($value) {
        $category = Category::where('title', $value)->first();
        if ($category) {
            return $category;
        }
        App::abort(404);
    }
});

Route::get('{category}/{subcategory?}', 'CategoriesController@get');

Update:

Now i made this, but i think it's not the best solution.

Route::bind('category', function ($value) {
    $category = Category::where('title', $value)->whereNull('parent_id')->first();
    if (!$category) {
        App::abort(404);
    }

    Route::bind('subcategory', function ($value, $route) use ($category) {
        if ($value) {
            $subcategory = Category::where('title', $value)->where('parent_id', $category->id)->first();
            if (!$subcategory) {
                App::abort(404);
            }

            return $subcategory;
        }
    });

    return $category;
});
Laurence
  • 58,936
  • 21
  • 171
  • 212

3 Answers3

3

You may try this and should work, code is self explanatory (ask if need an explanation):

Route::bind('category', function ($value) {
    $category = Category::where('title', $value)->first();
    if (!$category || $category->parent_id) App::abort(404);
    return $category;
});

Route::bind('subcategory', function ($value, $route) {
    $category = $route->parameter('category');
    $subcategory = Category::where('title', $value)->whereParentId($category->id);
    return $subcategory->first() ?: App::abort(404); // shortcut of if
});

Route::get('{category}/{subcategory?}', 'CategoriesController@get');

Update: (As OP claimed that, there is no parameter method available in Route class):

/**
 * Get a given parameter from the route.
 *
 * @param  string  $name
 * @param  mixed  $default
 * @return string
 */
public function getParameter($name, $default = null)
{
    return $this->parameter($name, $default);
}

/**
 * Get a given parameter from the route.
 *
 * @param  string  $name
 * @param  mixed  $default
 * @return string
 */
public function parameter($name, $default = null)
{
    return array_get($this->parameters(), $name) ?: $default;
}
The Alpha
  • 143,660
  • 29
  • 287
  • 307
  • In Laravel 4 `Route` class don't have `parameter()` method. – Dmitry Gres Feb 19 '14 at 20:37
  • @DmitryGres, There is a `parameter` method in the `Route` class, make sure you checked the right `class`. – The Alpha Feb 19 '14 at 20:42
  • There isn't a `paremeter` method (http://laravel.com/api/class-Illuminate.Routing.Route.html). When i try laravel throws `FatalErrorException` with message "Call to undefined method Illuminate\Routing\Route::parameter()". – Dmitry Gres Feb 19 '14 at 21:48
  • @DmitryGres, [Check this, Laravel 4.1](http://laravel.com/api/4.1/) and you can use [getParameter](http://laravel.com/api/source-class-Illuminate.Routing.Route.html#_getParameter) method as well if you are using older version. – The Alpha Feb 19 '14 at 21:56
  • I tried `$route->getParameter('category');`. Laravel throws `FatalErrorException` with message "Maximum function nesting level of '100' reached, aborting!". – Dmitry Gres Feb 19 '14 at 21:57
  • @DmitryGres, [Maximum function nesting level](http://stackoverflow.com/questions/4293775/increasing-nesting-functions-calls-limit). – The Alpha Feb 19 '14 at 21:59
1

I can't test this right now for you, but the closure function receives a $value and $route. The last one is a instance of '\Illuminate\Routing\Route' (http://laravel.com/api/class-Illuminate.Routing.Route.html), and perhaps you could use the getParameter() method to retrieve some data....

Rob Gordijn
  • 6,381
  • 1
  • 22
  • 29
  • I tried `$route->getParameter('category');`. Laravel throws `FatalErrorException` with message "Maximum function nesting level of '100' reached, aborting!". – Dmitry Gres Feb 18 '14 at 13:42
  • try `resolveParameter('category')`, if that doesn't work, I give up. – Rob Gordijn Feb 18 '14 at 13:49
1

I recently ran into same issues while trying to auto validate my stories existence inside my Session Model. So, i tried to check my Story model existence inside my Session Model using model bindings.

This is my solution

$router->bind('stories', function($value, $route) {
        $routeParameters = $route->parameters();
        $story = Story::where('id', $value)->where('poker_session_id',    $routeParameters['poker_sessions']->id)->first();

        if (!$story) {
            throw new NotFoundHttpException;
        }

        return $story;
    });

You can actually get route parameters using $route->parameters(), which returns an array. In my case, "poker_sessions" key contain an PokerSession Model, which i want.

Please be careful and use this only when you have a /category/{category}/subcategory/{subcategory} url like. Not subcategory without any {category}.

Good luck!.

Kun Andrei
  • 266
  • 3
  • 8