【问题标题】:Laravel resource: How define the name of the key parameter?Laravel 资源:如何定义关键参数的名称?
【发布时间】:2016-06-29 15:16:07
【问题描述】:

当您使用Route::resource('recipe', 'RecipeController'); 定义资源时,会定义以下路由:/photo/{photo}/edit,一旦您定义了所有资源,您将拥有如下内容:

  • /recipes/{recipes}/edit
  • /allergens/{allergens}/edit
  • /ingredients/{ingredients}/edit

因为我的所有记录都使用 id 作为主键 (MongoDB),所以我希望使用 {id},如下所示:

  • /recipes/{id}/edit
  • /allergens/{id}/edit
  • /ingredients/{id}/edit

我在Router 类中进行了挖掘,但我不知道如何指定它。

当我使用Form::model($record) 创建一个表单时,我会得到类似/recipes/{recipes} 这样的操作,因为recipes$record 的属性。

如何将key参数的名称定义为id而不是recipesallergensingredients

【问题讨论】:

  • 那么您关心的是路由还是表单构建器?
  • 我更关心路线,我希望它们遵循相同的模式。例如{resource}/{id}/edit
  • 那就这样吧。但请记住嵌套资源 - 就像在答案中一样。

标签: laravel laravel-routing


【解决方案1】:

要更改Route::resource 的参数名称,您需要自定义ResourceRegistrar 实现。

您可以通过以下方式以最短的方式实现这一目标:

// AppServiceProvider (or anywhere you like)
public function register()
{
  $this->app->bind('Illuminate\Routing\ResourceRegistrar', function ($app) {

    // *php7* anonymous class for brevity,
    // feel free to create ordinary `ResourceRegistrar` class instead
    return new class($app['router']) extends \Illuminate\Routing\ResourceRegistrar 
    {

      public function register($name, $controller, array $options = [])
      {
        if (str_contains($name, '/')) {
          return parent::register($name, $controller, $options);
        }

        // ---------------------------------
        // this is the part that we override
        $base = array_get($options, 'param', $this->getResourceWildcard(last(explode('.', $name))));
        // ---------------------------------

        $defaults = $this->resourceDefaults;

        foreach ($this->getResourceMethods($defaults, $options) as $m) {
          $this->{'addResource'.ucfirst($m)}($name, $base, $controller, $options);
        }
      }
    };
  });
}

现在您的路线将如下所示:

Route::resource('users', 'UsersController', ['param' => 'some_param'])
/users/{some_param}

// default as fallback
Route::resource('users', 'UsersController')
/users/{users}

请注意,这种方式不适用于嵌套资源,因此它们将混合使用默认和自定义行为,如下所示:

Route::resource('users.posts', 'SomeController', ['param' => 'id'])
/users/{users}/posts/{id}

【讨论】:

  • 我希望这样更简单:github.com/ICanBoogie/…OPTION_ID_NAME,但您的代码会做得很好。非常感谢贾里德!
【解决方案2】:

我知道这是一个 4 岁的问题,但对于任何使用谷歌搜索的人来说;您可以传递第三个参数来覆盖键命名:

Route::resource('ingredients', 'IngredientController', ['parameters' => ['ingredients' => 'id']]);

或者

Route::resource('ingredients', 'IngredientController')->parameters(['ingredients' => 'id']);

【讨论】:

    【解决方案3】:

    您可以将您的 id 传递给不需要将参数 {recipes} 更改为 {id} 的路由,因为参数只是一个占位符。

    所以

     public function edit($recipes){
        // code goes hr
     }
    

    和这个一样

     public function edit($id){
        // code goes hr
     }
    

    这条路线/recipes/{recipes}/edit

    【讨论】:

    • 感谢您的回答,Form::model 也有问题,因为记录中没有recipes 属性,我最终得到/recipes/{recipes} 路由。我更新了我原来的帖子。
    • 哦,好吧,我猜你正在使用路由模型绑定。
    • @olvlvl 路线中的内容并不重要,因为 oseinow 说它只是一个占位符。我认为问题出在其他地方。无论如何,您提交表单后遇到的错误是什么?
    猜你喜欢
    • 1970-01-01
    • 2019-10-02
    • 2021-11-09
    • 1970-01-01
    • 2018-10-04
    • 2017-02-12
    • 2017-09-24
    • 2019-05-30
    • 1970-01-01
    相关资源
    最近更新 更多