Reputation: 1746
Can we have a single controller for multiple routes, and get the parameter?
Currently, I have these routes:
Route::resource('/customers', 'CustomerController');
Route::resource('/agents', 'AgentController');
And a CustomerController
and a AgentController
with all resource functions working.
But as CustomerController
and AgentController
are almost same except for one database field, i.e. group_id
. I was thinking to use one controller i.e. PartyController
and one route as:
Route::resource('/parties/customers', 'PartyController ');
Route::resource('/parties/agents', 'PartyController ');
or if someone suggests:
Route::resource('/parties/{group}', 'PartyController ');
I have been searching for a while but finding it hard to follow this path. I've added this code in the constructor of PartyController
, to check the calling route:
$path = Request::capture()->path();
$this->group = ucwords(explode("/", $path)[1]);
echo($this->group );
All seems to be going well till here. But when in my index.blade.php
, I have this statement:
<p>{{ link_to_route('parties.create', 'Add new') }}</p>
I get an exception:
Route [parties.create] not defined.
I've tried multiple combinations, without any success and more errors come through, like accessing /parties/customers/create
doesn't work now.
So, is it possible anyway or should I abandon this idea?
EDIT: My question is different from Same Laravel resource controller for multiple routes as I am not using a trait.
Upvotes: 4
Views: 5571
Reputation: 1746
I did it by using my own approach, I used the same routes.
Route::resource('/parties/agents', 'PartyController');
Route::resource('/parties/customers', 'PartyController');
and in constructor of PartyController
$path = Request::capture()->path();
$group = strtolower(explode("/", $path)[1]);
Now I've the $group variable to identify which group I am working with.
And in my blade documents I replaced parties.create with $group.create
<a href="{{ route($group.'.create')}}" > Add new </a>
Same for other routes.. Now it is working just as I wanted.
Thank all for help.
Upvotes: 2
Reputation: 789
So, first you define routes with next line:
Route::resource('/parties/agents', PartiesAgentsController::class);
Route::resource('/parties/customers', PartiesCustomersController::class);
Then you might need some parties in the REST style:
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)
{
}
}
Inside the construct method of this controller I am making some checks and other operations as you could see. Also I use repositories... It is No DDD).
Then, I can use all above like:
class PartiesAgentsController extends PartiesController
{
/**
* Create an instance of the PartiesAgentsController class
*
* @param EntryRepositoryInterface $repository
*/
public function __construct(PartyAgentRepositoryInterface $repository)
{
parent::__construct($repository);
}
}
And the same would be for customers...
Upvotes: 1
Reputation: 705
As I think right now... It would be nice to using class inheritance! :D
You can define PartyController
as a parent of both CustomerController
and AgentController
(both of them extends PartyController
).
So, move your common methods into PartyController
and call them from Customer/Agent
controllers. :)
Upvotes: 4
Reputation: 1446
<p>{{ link_to_route('parties.create', 'Add new') }}</p>
You missed the variable parameter you added, it should be
<p>{{ link_to_route('parties.' . $group . '.create', 'Add new') }}</p>
Upvotes: 1
Reputation: 111899
If I were you, I would use:
Route::resource('/customers', 'CustomerController');
Route::resource('/agents', 'AgentController');
Now you can make AgentController
extending CustomerController
(or any other controller you want) so they can reuse same code. If needed you can set in constructor some properties for example group to know if you are dealing with agents or customers.
To make your routes working you can pass extra variable from controller to view, to have in your blade:
<p>{{ link_to_route($group.'.create', 'Add new') }}</p>
Upvotes: 6