Laravel 5.3 - Model that can be created by multiple Controllers

Asked

Viewed 342 times

3

Good afternoon, use Laravel 5.3 as back-end of a project and I will try to explain in the most succinct way the problem.

Problem: In my project I have the Duplicate model and the Contract.

  1. A contract creates multiple duplicates by the Contratocontroller
  2. A duplicate can be created by another controller called Locacaocontroller.
  3. And finally the duplicate can be created by Duplicatacontroller via store method().

In the database I have the tables:

duplicatas
contratos

They all share basically the same code

$duplicata = new Duplicata()
$duplicata->valor = $request->valor
$duplicata->descricao = $request->descricao
$duplicata->contrato_id = $request->contrato_id
$duplicata->save()

But now I’m going to add our number to the database, and I’m going to have to copy and paste the programming logic into all 3 controllers.

And I found this a bad programming practice and I intend to unify the way duplicates are created, but how do I do that? I’m doing it all wrong?

  • 1

    Create the Duplicates only in Duplicatacontroller, Integrate the dependency where you need to create duplicates and use only the store method of Duplicatacontroller, it makes no sense for the same function in a lot of different places if you can reuse :)

  • But only this method is repeated? If you want, you can create a specific Controller (e.g., Duplicationscontroller) with the methods that will be shared and "extend" it in the 3 controllers you need.

  • Or create a class that does this calls in the App Classname and invokes the function. GGWP.

  • The deal is that when a contract is created the system triggers a series of creation of duplicates from the past parameters (maturity, contract value, etc.) via transaction, because in case of an error in the creation of one the entire contract is deleted.

  • @Felipepaetzold in the case of the injection of a Controller into another one as I would call the store method? And what to do with the return of it? (Return Response()->json('Duplicate successfully created, 200'))?

  • 1

    @Cassiano created an answer more or less with a direction for you to follow, there are several ways to do this elegantly, I hope it helps

Show 1 more comment

4 answers

5


Create this method within one Controller of Duplicata:

public function criaDuplicata($request)
{
    $duplicata = new Duplicata()
    $duplicata->create($request);
    return $duplicata;
}

public function store(Request $request)
    {
        $this->criaDuplicata($request->all());
        return view("suaView", []);
    }

And call her even in your store who receives a Request. So you can use this dependency elsewhere, for example in ContratoController.

public function __construct(DuplicataController $duplicataController) //Aqui está a injeção de dependência
{
    $this->duplicataController = $duplicataController;
}

public function geraDuplicata($duplicata)
{
    $this->duplicataController->criaDuplicata($duplicata);
}

2

I would, so traits, which is a practice used in framework , where the controllers can inherit this code.

Example

trait

trait DuplicatasOfControllers
{
    public function inserirDuplicata(Request $request) 
    {
        $duplicata              = new Duplicata()
        $duplicata->valor       = $request->valor
        $duplicata->descricao   = $request->descricao
        $duplicata->contrato_id = $request->contrato_id
        $duplicata->save();
    }
}

controllers

class ContratoController 
{
    use DuplicatasOfControllers;
}

class DuplicataController 
{
    use DuplicatasOfControllers;

    public function store(Request $request)
    {
        $this->inserirDuplicata($request);
        return view("suaView", []);
    }
}

class LocacaoController
{
    use DuplicatasOfControllers;
}

Changes in duplicate code will be made in the trait DuplicatasOfControllers.

2

I created a folder called Classes inside App. And I created a file with the class name.

Kind in your case may be CadastroDuplicata.

<?php

    namespace App\Classes;

    class CadastroDuplicata{
        public static function create($request){
            $duplicata              = new Duplicata()
            $duplicata->valor       = $request->valor
            $duplicata->descricao   = $request->descricao
            $duplicata->contrato_id = $request->contrato_id
            $duplicata->save();
        }
    }

Controller

use App\Classes\CadastroDuplicata

.
.
.

CadastroDuplicata::create($request);

Then you call the function in any other Controller this way, you can create more parameters as well. Don’t forget to call the class of Models in Class.

Even better you can do it on Model of Duplicate. Create that same function inside instead of creating a class in a separate folder.

I did it because I like it.

  • I liked the answer, but the question that remained is: Flee a little from the standards of the Laravel of MVC. Maintaining this model in the future would be a problem?

  • This is Object Orientation. It would certainly be permissible to do this and is easy to maintain.

2

Injection has already been shown (IMHO the best), static method, so let’s go to one more alternative and you see which one adapts best to what you need.

What you need can be done from inheritance:

abstract class podeDuplicar extends BaseController{

    public function gerarDuplicata(){
        $duplicata = new Duplicata();
        $duplicata->valor = $request->valor;
        $duplicata->descricao = $request->descricao;
        $duplicata->contrato_id = $request->contrato_id;
        $duplicata->save();
    }

}

So just give the extend:

class ContratoController extends podeDuplicar { /* Resto da lógica aqui */ }
class LocacaoController extends podeDuplicar { /* Resto da lógica aqui */ }
class DuplicataController extends podeDuplicar { /* Resto da lógica aqui */ }

So anyone can just do:

(new ContratoController)->gerarDuplicata();
(new LocacaoController)->gerarDuplicata();
(new DuplicataController)->gerarDuplicata();

And if you want to keep the store() of DuplicataController, just pull the method:

class DuplicataController extends podeDuplicar {
    public function store(){ 
        $this->gerarDuplicata();
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.