Registration in more than one table with Laravel

Asked

Viewed 1,107 times

1

So, I have 3 tables (doctors, addresses and phones), first I do the insertion in the medical table using the store method that is in its own controller, and I take the id created for it and insert in the other tables along with the other information. For this I called the other classes into this method, rather than using their methods.

The following code is working, but I’d like to know if this is really the best way to do it. Is it correct to do everything only in the medical class controller and ignore the insertion methods of the other classes? I couldn’t think of anything using the three-class controller.

I will not use any method of the telephone and address classes, because even in the edition they will be changed in the medical class. No problem deleting their controller and leaving only the Model right?

PS: I changed the code, now it’s smaller and cleaner.

Tables: medicos(id, nome, Descricao, id_cidade); enderecos(id, rua, numero, sala, id_medico); telefones(id, id_medico, numero). A doctor will only have one address (street, number, etc.) but may have more than one phone.

Medicocontroller

public function store(Request $request)
{
    $dataForm = $request->all();

    $medico = $this->medico->create($dataForm);

    $dataForm['id_medico'] = $medico->id;

    Endereco::create($dataForm);

    foreach($dataForm['fone'] as $fone)
    {
        $dataForm['fone'] = $fone;
        Telefone::create($dataForm);
    }
}

Model Medico

    namespace App\Models\painel;

use Illuminate\Database\Eloquent\Model;

class Medico extends Model
{
    protected $fillable = [
        'nome', 'id_cidade', 'created_at', 'updated_at'
    ];
}

Model Endereco

    namespace App\Models\painel;

use Illuminate\Database\Eloquent\Model;

class Endereco extends Model
{
    public $timestamps = false;

    protected $fillable = [
        'rua', 'numero', 'sala', 'id_medico'
    ];
}

Model Telefone

namespace App\Models\painel;

use Illuminate\Database\Eloquent\Model;

class Telefone extends Model
{
    public $timestamps = false;

    protected $fillable = [
        'fone', 'id_medico'
    ];
}

  • There is, if code can be improved, but put the 3 models and their relationships I’m not understanding them

  • I changed the post, now maybe it’s easier to understand. Basically my question is q how the data will be in the same form, they will be sent to the same place (doctor’s controller), then the insertion of the three tables will be made in the same method. Leaving aside the methods of the other classes, is that correct? If yes, I will no longer use their methods, I can delete your controllers?

1 answer

1


We will start your answers by the problems, when using the should make the relationships that are explained by the documentation and are of great value not only at the time of recovery, but also in the operations of create, delete and change. In your specific case it seems to me that the relations are as follows:

  • 1 Medic has any or 1 Addressee, and;
  • 1 Medic has none or 1 or more Phones.

The first ratio would be 1 to 1 as described in the documentation and the second ratio would be 1 for many also described in the documentation. The important thing is to keep in mind that this is a common and widely used practice and the can calmly make this relationship process, with the operations of CRUD.

I am going to propose a minimal example, through what I see in your question and this is close to your real model.

Minimal example:

Classes of the Eloquent

Doctor

<?php namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Medico extends Model
{
    protected $primaryKey = 'id';
    protected $table = 'medicos';
    protected $fillable = ['nome', 'id_cidade'];
    protected $dates = ['created_at', 'updated_at'];
    public $timestamps = true;

    public function endereco()
    {
        return $this->hasOne(Endereco::class, 'id_medico','id');
    }

    public function telefones()
    {
        return $this->hasMany(Telefone::class, 'id_medico', 'id');
    }
}

Addressee

<?php namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Endereco extends Model
{
    protected $primaryKey = 'id_medico';
    protected $table = 'enderecos';
    protected $fillable = ['rua', 'numero', 'sala', 'id_medico'];
    public $incrementing = false;
    public $timestamps = false;

    public function medico()
    {
        return $this->belongsTo('App\Peoples', 'id_medico', 'id');
    }
}

Telephone

<?php namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Telefone extends Model
{
    protected $primaryKey = 'id';
    protected $table = 'telefones';
    protected $fillable = ['fone', 'id_medico'];
    public $timestamps = false;

    public function medico()
    {
        return $this->belongsTo(Medico::class, 'id_medico', 'id');
    }
}

Note that each class has its settings clear because, its fields did not follow the default nomenclature of , no problems, only that not following the nomenclature should manually configure the fields, all this explained in the Eloquent Model Conventions documentation.

The purpose of the question is to know if the method can be simplified and using a cleaner coding, and yes this is possible, fixing the data would thus record a doctor with your address and your phones:

Operations:

//Criando Médico
$medico = Medico::create(['nome' => 'Medico A', 'id_cidade' => 1]);
if ($medico) {
    //Granvando Endereco;
    $medico->endereco()
           ->create([
               'rua' => 'Rua A',
               'numero' => 'Numero A',
               'sala' => 'Sala A'
           ]);
    //Gravando Telefones;
    $medico->telefones()->createMany([
        ['fone' => '1152526969'],
        ['fone' => '1169695252']
    ]);

    return $medico;
}

this would be the recording of the data with fictitious data and fixed in the code, but, for its code would be something like this:

$medico = Medico::create($request->all());
if ($medico) 
{    
    $medico->endereco()->create($request->all());
    foreach($request->only('fone')['fone'] as $f) 
    {
        $medico->telefones()->create(['fone' => $f]);
    }
    return $medico;
}

the code decrease, the pattern proposed by the settings of each Model Eloquent and the facilities of framework Laravel propose to us the codes very clean and of extreme capacity for development.

Observing: in the table of Doctor has a relationship with Cities where 1 doctor belongs to a City your relationship inverse a City can have several doctors, is the same relationship of Doctor and Phone if you need to set up just follow the same example.

References:

  • The phone insertion part works if I leave with the dummy data, but not if I leave with the data coming from the form. Shouldn’t I leave this inside a foreach to go through all the numbers? My input looks like this: <input type="text" name="phone[]">

  • The following error appears: SQLSTATE[HY000]: General error: 1364 Field 'fone' doesn’t have a default value (SQL: Insert into telefones (id_convenio, updated_at, created_at) values (14, 2017-07-03 20:45:48, 2017-07-03 20:45:48))

  • @Diegovieira the error is another friend, the error is in the name of the field take a look at this in the database and your code please?

  • It is with the name "phone" everywhere, it is right to put the name of the input with bracket right?

  • @Diegovieira I already know why it’s coming like this fone[0] = "valor", fone[1] = "valor" that’s why. Give a var_dump($request->only('fone')) and tell me the result should not be coming key and value!

  • array(1) { ["fone"]=> array(2) { [0]=> string(3) "123" [1]=> string(3) "456" } }

  • @Diegovieira looks there the code... I edited the answer

  • It worked, thank you very much for your help!

Show 3 more comments

Browser other questions tagged

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