Laravel의 리소스 컨트롤러에 새로운 메소드 추가


141

라 라벨의 리소스 컨트롤러에 새로운 메소드를 추가 할 수 있는지, 어떻게 하는지를 알고 싶습니다.

나는이 방법이 기본값이라는 것을 알고 있습니다 (색인, 생성, 저장, 편집, 업데이트, 파괴). 이제 동일한 컨트롤러에 메소드와 경로를 추가하고 싶습니다.

가능합니까?

답변:


261

리소스를 등록 하기 전에 해당 메서드에 대한 경로를 별도로 추가하십시오 .

Route::get('foo/bar', 'FooController@bar');
Route::resource('foo', 'FooController');

7
새 메소드는 그 이상이어야 합니다. ::resource그렇지 않으면 "모델에 대한 쿼리 결과가 없습니다"라는 오류 메시지가 표시됩니다.
mpen

{id}와 같은 매개 변수를 어떻게 전달 하시겠습니까? 현재 route.php 에 사용자 정의 메소드를 인라인으로 코딩했습니다 (예 : laravel.com/docs/5.1/routing#route-parameters ). 이상적으로는 FooController에서 실행되도록 매개 변수를 전달하고 싶습니다.
ATutorMe

1
문제가 발견되었습니다-경로 구문에 없었습니다. 실제로 내가 사용하고있는 일부 사용자 정의 미들웨어에있었습니다! Route :: get ( 'foo / {id} / bar', 'FooController @ bar'); id를 bar ($ id) 메소드에 전달합니다. 감사!
ATutorMe

누군가 사용자 지정 경로가 리소스 경로보다 높아야하는 이유를 설명 할 수 있습니까 ??? 나는 ... 몇 가지 테스트를 수행하고 위 또는 아래 퍼팅 사이에 diference이없는 것 같습니다 한
리카르도 Vigatti

3
@RicardoVigatti-리소스가이 경로를 등록합니다 : Route::get('foo/{id}', ...). 이렇게 foo하면을 (를) 포함하여 하나의 추가 세그먼트로 시작하여 모든 경로를 삼킬 수 foo/bar있습니다.
Joseph Silber 1

32

방금 GET "delete"메소드를 추가하기 위해 그렇게했습니다.

파일을 만든 후 추가하면됩니다.

'AntonioRibeiro\Routing\ExtendedRouterServiceProvider',

app / config.php의 '제공자'에게

이 동일한 파일에서 라우트 별명을 편집하십시오.

'Route'           => 'Illuminate\Support\Facades\Route',

로 변경

'Route'           => 'AntonioRibeiro\Facades\ExtendedRouteFacade',

해당 파일이 자동으로로드되는지 확인하고 composer.json에있는 일부 디렉토리 ( "autoload"섹션)에 있어야합니다.

그런 다음 다음을 수행하면됩니다.

Route::resource('users', 'UsersController');

그리고이 (마지막 줄을 보면) 다음을 실행하면 결과가 나타납니다 php artisan routes.

노선 목록 그것들은 내 소스 파일입니다.

ExtendedRouteFacade.pas

<?php namespace AntonioRibeiro\Facades;

use Illuminate\Support\Facades\Facade as IlluminateFacade;

class ExtendedRouteFacade extends IlluminateFacade {

    /**
     * Determine if the current route matches a given name.
     *
     * @param  string  $name
     * @return bool
     */
    public static function is($name)
    {
        return static::$app['router']->currentRouteNamed($name);
    }

    /**
     * Determine if the current route uses a given controller action.
     *
     * @param  string  $action
     * @return bool
     */
    public static function uses($action)
    {
        return static::$app['router']->currentRouteUses($action);
    }

    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor() { return 'router'; }

}

ExtendedRouter.pas

<?php namespace AntonioRibeiro\Routing;

class ExtendedRouter extends \Illuminate\Routing\Router {

    protected $resourceDefaults = array('index', 'create', 'store', 'show', 'edit', 'update', 'destroy', 'delete');

    /**
     * Add the show method for a resourceful route.
     *
     * @param  string  $name
     * @param  string  $base
     * @param  string  $controller
     * @return void
     */
    protected function addResourceDelete($name, $base, $controller)
    {
        $uri = $this->getResourceUri($name).'/{'.$base.'}/destroy';

        return $this->get($uri, $this->getResourceAction($name, $controller, 'delete'));
    }

}

ExtendedRouteServiceProvider.pas

<?php namespace AntonioRibeiro\Routing;

use Illuminate\Support\ServiceProvider;

class ExtendedRouterServiceProvider extends ServiceProvider {

    /**
     * Indicates if loading of the provider is deferred.
     *
     * @var bool
     */
    protected $defer = true;

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->app['router'] = $this->app->share(function() { return new ExtendedRouter($this->app); });
    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
        return array('router');
    }

}

3
Laravel 5 이상에 대해서도 동일하게 제공 할 수 있습니까? 나는 이것을 재현하려고 노력했지만 ... 컨테이너에서 '경로'액세서를 어디에 등록하고 있는지 찾을 수없는 것 같습니다.
TipuZaynSultan

파일 확장자가 .pas 인 이유는 무엇입니까?
Thiago Dias

22

예, 가능합니다 ..

내 경우에는 HTTP POST 메서드에서 /data.json에 대한 요청을 처리하기 위해 method : data를 추가합니다.

내가 한 일.

먼저 Illuminate \ Routing \ ResourceRegistrar 를 확장 하여 새로운 분석법 데이터 를 추가 합니다

<?php

namespace App\MyCustom\Routing;

use Illuminate\Routing\ResourceRegistrar as OriginalRegistrar;

class ResourceRegistrar extends OriginalRegistrar
{
    // add data to the array
    /**
     * The default actions for a resourceful controller.
     *
     * @var array
     */
    protected $resourceDefaults = ['index', 'create', 'store', 'show', 'edit', 'update', 'destroy', 'data'];


    /**
     * Add the data method for a resourceful route.
     *
     * @param  string  $name
     * @param  string  $base
     * @param  string  $controller
     * @param  array   $options
     * @return \Illuminate\Routing\Route
     */
    protected function addResourceData($name, $base, $controller, $options)
    {
        $uri = $this->getResourceUri($name).'/data.json';

        $action = $this->getResourceAction($name, $controller, 'data', $options);

        return $this->router->post($uri, $action);
    }
}

그런 다음 새 ServiceProvider를 만들 거나 AppServiceProvider를 대신 사용하십시오.

메소드 부팅 에서 다음 코드를 추가하십시오.

    public function boot()
    {
        $registrar = new \App\MyCustom\Routing\ResourceRegistrar($this->app['router']);

        $this->app->bind('Illuminate\Routing\ResourceRegistrar', function () use ($registrar) {
            return $registrar;
        });
    }

그때 :

경로에 추가하십시오 :

Route::resource('test', 'TestController');

확인 php artisan route:list 하면 새로운 방법 '데이터'를 찾을 수 있습니다


귀하의 솔루션이 저에게 효과적입니다.이 코드를 사용하여 몇 달 후에 문제가 발견 된 경우 알려주시겠습니까?
Ricardo Vigatti

감사합니다 @RicardoVigatti. 나는 laravel 5.2 이후 이것을 사용했으며 이제는 L5.3이있는 최근 프로젝트에서 이것을 사용하고 아무런 문제가 없습니다. 당신이 하나 있으면 알려주세요, 내가 당신을 도울 수 있습니다 ..
Mokhamad Rofi'udin

좋아, 나는 이것을 5.0 프로젝트에서 구현하고있다. 이 솔루션은 매우 일관된 것처럼 보이지만 문제가 해결되면 몇 주 후에 발생합니다.
Ricardo Vigatti

@ MokhamadRofi'udin 귀하의 솔루션을 구현했으며 새로운 경로가 경로 목록에 추가되었지만 해당 방법이 추가되지 않은 것 같습니다. 뭔가 빠졌습니까?
Siavosh

@Siavosh 그냥 당신의 방법을 쓰기 컨트롤러 즉 I add 메소드 데이터 () :`공공 기능 데이터 (요청 $ 요청) {}`
Mokhamad Rofi'udin

13
Route::resource('foo', 'FooController');
Route::controller('foo', 'FooController');

이것을 시도해보십시오 .getData () 등과 같은 추가 메소드를 넣으십시오. 이것은 route.php를 깨끗하게 유지하는 데 효과적이었습니다.


야스이 작동합니다. Laravel 5.1 설명서에서는 Route :: resource와 Route :: controller를 리소스 컨트롤러 보완에 대해 언급 한 것이 아니라 함께 사용할 수 있다고 언급하지 않았습니다. 그래서 이것은 혼란 스럽습니다. 그러나 당신의 ans는 이것들이 함께 사용될 수 있음을 증명했습니다
Amir

죄송합니다 Hassan jamal,이 두 가지가 함께 작동하지 않습니다. 이제 Route :: resource
Amir

3

Laravel 사용> 5 경로 폴더에서 web.php 파일 찾기 방법 추가

route :: resource를 사용하면 컨트롤러에서 한 줄로 색인, 표시, 저장, 업데이트, 삭제하는 모든 메소드를 라우팅 할 수 있습니다

Route::get('foo/bar', 'NameController@bar');
Route::resource('foo', 'NameController');

1

새 방법과 해당 방법에 대한 경로를 추가하십시오.

컨트롤러에서 :

public function foo($bar=“default”)
{
      //do stuff
}

웹 경로에서

Route::get(“foo/{$bar}”, MyController@foo”);

컨트롤러의 메소드가 공개인지 확인하십시오.


-1

이것은 꽤 잘 작동합니다. 더 많은 경로를 추가 할 필요가 없습니다. 다음과 같이 리소스 컨트롤러의 show 메소드를 사용하십시오.

public function show($name){

 switch ($name){
   case 'foo':
    $this -> foo();
    break;
   case 'bar':
    $this ->bar();
    break; 
  defautlt:
    abort(404,'bad request');
    break;
 }

}
public function foo(){}
publcc function bar(){}

기본값을 사용하여 사용자 정의 오류 페이지를 발생시킵니다.


2
이것은 실제 코드 냄새처럼 느껴집니다. 컨트롤러가 여러 작업을 처리하기를 원하지 않습니다.
RonnyKnoxville
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.