Laravelのリソースコントローラーに新しいメソッドを追加する


141

Laravelのリソースコントローラーに新しいメソッドを追加できるかどうか、およびその方法を知りたいです。

これらのメソッドがデフォルトであることを知っています(インデックス、作成、保存、編集、更新、破棄)。次に、同じコントローラにメソッドとルートを追加します。

それは可能ですか?

回答:


261

リソースを登録する前に、そのメソッドへのルートを個別に追加するだけです。

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

7
あなたの新しい方法が行かなければならないことに注意の上::resourceそうしないと、エラーメッセージ、「モデルなしのクエリ結果」を得ます。
mpen 2014年

{id}のようなパラメーターをどのように渡しますか?現在、routes.phpにカスタムメソッドをインラインでコード化しています(ここの例のように laravel.com/docs/5.1/routing#route-parameters)。理想的には、FooControllerで実行するパラメーターを渡します。
ATutorMe 2016年

1
問題が見つかりました-ルート構文にありませんでした。実際、私が使用しているいくつかのカスタムミドルウェアにありました!Route :: get( 'foo / {id} / bar'、 'FooController @ bar'); idをbar($ id)メソッドに渡します。ありがとう!
ATutorMe 2016年

カスタムルートがリソースルートより上になる理由を誰かが説明できますか?私はいくつかのテストを実行しましたが、上または下に置くことに
違い

3
@RicardoVigatti-リソースはこのルートを登録します:Route::get('foo/{id}', ...)。これによりfoo、をはじめとする1つの追加セグメントから始まるすべてのルートが飲み込まれますfoo/bar
ジョセフSilber

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 2016

ファイルに拡張子.pasが付いているのはなぜですか?
Thiago Dias

22

ええ、それは可能です。

私の場合、method:dataを追加して、HTTP POSTメソッドで/data.jsonのリクエストを処理します。

これは私がやったことです。

まず、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を使用します。

メソッドbootで、次のコードを追加します。

    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を使用する最近のプロジェクトで使用しましたが、問題はありません。お持ちの場合は
お知らせ

いいですね、これを私の5.0プロジェクトに実装しています。解決策は非常に一貫しているように見えますが、問題が発生した場合は、数週間後に解決します。
Ricardo Vigatti 2016年

@ MokhamadRofi'udinソリューションを実装しました。新しいルートがルートリストに追加されましたが、対応するメソッドが追加されていないようです。何か不足していますか?
Siavosh 2016年

@Siavoshはコントローラにメソッドを書き込むだけです。つまり、メソッドdata()を追加します。`public function data(Request $ request){} `
Mokhamad Rofi'udin

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

これを試してください。getData()などの追加のメソッドを追加してください。これはroute.phpをクリーンに保つために機能しました


これは機能します。Laravel 5.1のドキュメントでは、Route :: resourceとRoute :: controllerを一緒に使用できることは言及されておらず、リソースコントローラの補足について言及されていました。したがって、これは混乱しています。しかし、あなたのansはこれらが一緒に使用できることを証明しました
Amir

ハッサンジャマール、申し訳ありません。これら2つは連携していません。では、Route :: resourceのみを使用している場合、コントローラーにカスタムpostメソッドを設定するにはどうすればよいですか
Amir

3

Laravel> 5を使用するルートフォルダーでweb.phpファイルを見つけてメソッドを追加する

route :: resourceを使用して、コントローラーでこれらのすべてのメソッドのインデックス、表示、保存、更新、破棄を1行でルーティングできます。

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.