srmacedo's avatar

Laravel [Resource route] + design patterns

Hi, My problem is this, I have approximately 47 classes, where more or less 5% have different methods. The point is, I feel I can standardize this with some design pattern.

But I'm kind of confused, let's say in the route I use the resource method to create the route of a certain location. That is, my class must have (create, index, show, destroy, update and etc) Since all the others are also being made in this pattern, my question is when it comes to calling the view through this design. And how would I call the pattern to perform such an action according to the location? Since the resource is standard.

I'm behind this just because of the code repetitions, which changes only the view and the model to be used.   Thanks and see you later. Sorry for english.

0 likes
9 replies
tobiasj's avatar

What do you mean with 47 classes, are they all resource related models (each represents a db table) or is it your controllers, or classes overall?

Note that on your routes you can use except and only:

Route::resource('my-models', 'MyModelsController', ['except' => ['delete', 'destroy']]); // this resources should not be deleted

If they are all models (and you do really need all of them) try to categorize them and use some kind of factory, repository for instantiation. Maybe you could use polymorphism too (laravel supports that out of the box).

1 like
srmacedo's avatar

Thanks for answering. I am developing a project management, so the amount of classes.

And each class responds by a model ie I need the CRUD. However I am repeating the same code in all controllers I know I could use a pattern to standardize, but what would be the most appropriate way?

samalapsy's avatar

@SRMACEDO. You can have your Route Like this example

Route::resource('orders', ['middleware' => 'auth' ,'except' => ['show', 'index']], 'OrderController');

So you Controller would look like this

public function index(){
    //Fetch All Orders Here
    $orders = Order::all();
    return ('orders.index', compact('orders'));
}

public function show($id){
    //To Display One Order Details
    $order = Order::findOrFail($id);
    return ('orders.show', compact('order'));
}

public function create(){
    //A form to create a new order
    return ('orders.create');
}


public function store(Request $request){
    //Saves the new created Order
    // This returns redirect to your desired route
}



public function edit($id){
    //Find an Order by id, display it on your edit.blade.php form
    $order = Order::findOrFail($id);
    return ('orders.edit', compact('order'));
}



public function update(Request $request, $id){
    //Does the same work as store() but it's only for updating an exiting row
}



public function destroy($id){
    //For deleting an Item by id
}

You should have a folder for your orders

orders
    - index.blade.php
    - create.blade.php
    - edit.blade.php
    - show.blade.php

Hope It Helps..

srmacedo's avatar

Hi Samalapsy. I already use that. My problem is repeating codes, in case all my classes use the same code and this is pissing me off.

Since I'm just giving ctrl c and ctrl v, I'm sure a design pattern will help me. But which?

Thank's bastão.

martinbean's avatar

@srmacedo If you can actually show us some of the code you’re repeating across classes, then we may be able to suggest solutions.

Right now you’re asking for answers for something no one knows anything about.

srmacedo's avatar

Hi, Martin. It's like I said, I use the default resource controller code.

Topvillas, maybe it's a good one. In my controller code I have (create, destroy, index, show, store, update and edit).

What changes from one controller to the other? Just the model and the view.

public function update(Request $request, $id)
{   
        
        $fields = Request::all();
        $option = ReturnController::returnQuery(OptionModel::class, 1, $id);
    
}

in other class

public function update(Request $request, $id)
{   
        
        $fields = Request::all();
        $option = ReturnController::returnQuery(CaseModel::class, 1, $id);
    
}
topvillas's avatar
Level 46

Yeah, give the abstract class a protected model property and override it in the controllers that inherit from it.

class AbstractThing
{
    protected $model = null;

    public function update(Request $request, $id)
    {
        $model->doSomething();
    }
}

class RealThing extends AbstractThing
{
    public function __constructor()
    {
        $this->model = new Model;
    }
}

Please or to participate in this conversation.