Laravel - несколько маршрутов ресурсов к одному контроллеру с аргументом


Можем ли мы иметь один контроллер для нескольких маршрутов и получить параметр?

В настоящее время у меня есть следующие маршруты:

Route::resource('/customers', 'CustomerController');
Route::resource('/agents', 'AgentController');

И CustomerController и AgentController со всеми работающими функциями ресурсов.

Но так как CustomerController и AgentController почти одинаковы, за исключением одного поля базы данных, т.Е. group_id. Я думал использовать один контроллер, т.Е. PartyController и один маршрут как:

Route::resource('/parties/customers', 'PartyController ');
Route::resource('/parties/agents', 'PartyController ');

Или если кто-то предложит:

Route::resource('/parties/{group}', 'PartyController ');

Я искал некоторое время, но нашел его трудно идти по этому пути. Я добавил этот код в конструктор PartyController, чтобы проверить маршрут вызова:

    $path = Request::capture()->path();
    $this->group = ucwords(explode("/", $path)[1]);
    echo($this->group );

Кажется, до сих пор все шло хорошо. Но когда в моем index.blade.php у меня есть это утверждение:

<p>{{ link_to_route('parties.create', 'Add new') }}</p>

Я получаю исключение:

Route [parties.create] not defined. 

Я перепробовал несколько комбинаций, без какого-либо успеха, и появилось больше ошибок, например, доступ к /parties/customers/create сейчас не работает.

Итак, возможно ли это в любом случае или мне следует отказаться от этой идеи?

РЕДАКТИРОВАТЬ: Мой вопрос таков отличается от Одного и того же контроллера ресурсов Laravel для нескольких маршрутов, так как я не использую признак.

Author: Khan, 2017-11-03

5 answers

На вашем месте я бы использовал:

Route::resource('/customers', 'CustomerController');
Route::resource('/agents', 'AgentController');

Теперь вы можете сделать AgentController расширение CustomerController (или любой другой контроллер, который вы хотите), чтобы они могли повторно использовать один и тот же код. При необходимости вы можете задать в конструкторе некоторые свойства, например группу, чтобы узнать, имеете ли вы дело с агентами или клиентами.

Чтобы ваши маршруты работали, вы можете передать дополнительную переменную из контроллера в представление, чтобы в вашем блейде было:

<p>{{ link_to_route($group.'.create', 'Add new') }}</p>
 5
Author: Marcin Nabiałek, 2017-11-09 19:37:08
<p>{{ link_to_route('parties.create', 'Add new') }}</p>

Вы пропустили добавленный вами переменный параметр, он должен быть

 <p>{{ link_to_route('parties.' . $group . '.create', 'Add new') }}</p>
 1
Author: N Mahurin, 2017-11-09 21:16:14

Как я думаю прямо сейчас... Было бы неплохо использовать наследование классов! :D

Вы можете определить PartyController как родителя обоих CustomerController и AgentController (оба они расширяют PartyController).

Итак, переместите свои общие методы в PartyController и вызовите их из контроллеров Customer/Agent. :)

 1
Author: YaserKH, 2017-11-12 08:14:47

Итак, сначала вы определяете маршруты со следующей строкой:

Route::resource('/parties/agents', PartiesAgentsController::class);
Route::resource('/parties/customers', PartiesCustomersController::class);

Тогда вам может понадобиться несколько вечеринок в стиле REST:

class PartiesController extends BaseController
{

    /**
     * The Entry Repository
     *
     * @var EntryRepositoryInterface
     */
    protected $repository;

    /**
     * Create an instance of the RestController class
     *
     * @param EntryRepositoryInterface $repository
     */
    public function __construct(EntryRepositoryInterface $repository)
    {
        parent::__construct();

        if (!$this->request->ajax())
        {
            return redirect('/');
        }

        $this->repository = $repository;
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request    $request
     * @return \Illuminate\Http\Response
     */
    public function store()
    {
    }

    /**
     * Display the specified resource.
     *
     * @param  int                         $slug
     * @return \Illuminate\Http\Response
     */
    public function show($slug)
    {
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int                         $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request    $request
     * @param  int                         $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int                         $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
    }

}

Внутри метода построения этого контроллера я выполняю некоторые проверки и другие операции, как вы могли видеть. Также я использую репозитории... Это не DDD).

Затем я могу использовать все вышеперечисленное, например:

class PartiesAgentsController extends PartiesController
{

    /**
     * Create an instance of the PartiesAgentsController class
     *
     * @param EntryRepositoryInterface $repository
     */
    public function __construct(PartyAgentRepositoryInterface $repository)
    {
        parent::__construct($repository);
    }

}

И то же самое было бы для клиентов...

 1
Author: Piterden, 2017-11-12 08:40:28

Я сделал это, используя свой собственный подход, я использовал те же маршруты.

Route::resource('/parties/agents', 'PartyController');
Route::resource('/parties/customers', 'PartyController');

И в конструкторе PartyController

$path = Request::capture()->path();
$group = strtolower(explode("/", $path)[1]);

Теперь у меня есть переменная $group, чтобы определить, с какой группой я работаю.

И в моих документах блейда я заменил parties.create на $group.create

<a href="{{ route($group.'.create')}}" > Add new </a>

То же самое для других маршрутов.. Теперь он работает именно так, как я хотел.

Спасибо всем за помощь.

 1
Author: Khan, 2017-11-13 08:35:00