How do I duplicate the records of a table, modifying the data of a column?

1

I explain:

I have a parts table with the fields id, name, dad_id, team_id, status .

I capture the data of the parts of the team that I want to copy:

$datos_partes = Partes::select(array('nombre', 'id_equipos', 'id_padre', 'status'))
->where('id_equipos', '=', $req->id)
->get()
->toArray();

I go through all the positions to edit the id_equipos and assign them the new one they will have, one by one I will register them in the db .

foreach($datos_partes as $clave => $elemento){
    $datos_partes[$clave]['id_equipos'] = $result['id'];
    Partes::create($datos_partes[$clave]);
}

Makes the records correctly, the problem I have is that the id_padre do not know how to modify them and update them to the new id that exist.

Result of what I am currently doing:

    
asked by Pablo Contreras 10.08.2017 в 11:27
source

2 answers

0

My solution was the following: is commented step by step

$id_equipo_old = $req->id; //id del equipo que traigo de la vista para copiar
$id_equipo_new = $result['id']; //id del equipo ya copiado

//obtengo todas las partes que pertenecen al registro anterior
$datos_partes_viejos = Partes::select(array('nombre', 'id_equipos', 'id_padre', 'status'))
->where('id_equipos', '=', $id_equipo_old)
->get()
->toArray();

//hago un recorrido de los registros y los vuelvo a registrar pero con el "id_equipos" nuevo
foreach($datos_partes_viejos as $clave => $elemento){
    $datos_partes_viejos[$clave]['id_equipos'] = $id_equipo_new;
    Partes::create($datos_partes_viejos[$clave]);
}

//obtengo las partes nuevas registradas 
$datos_partes_nuevos = Partes::select(array('id', 'nombre', 'id_padre'))
->where('id_equipos', '=', $id_equipo_new)
->get()
->toArray();

//creo una variable para almacenar los registros q se editaran
$ids = [];

//ahora recorro todos los registros nuevos
foreach($datos_partes_nuevos as $clave => $elemento){
    //entro en el registro si el "id_padre" es diferente de 0, puesto que los "id_padre" = 0 son copiados tal cual y no representan ningun error
    if($datos_partes_nuevos[$clave]['id_padre'] !== 0){

        //realizo una consulta y a cada registro busco los datos del "id_padre"
        $datos_partes_original = Partes::select(array('nombre', 'id_padre'))
        ->where('id', '=', $datos_partes_nuevos[$clave]['id_padre'])
        ->get()
        ->first()
        ->toArray();

        //relizo otra consulta en la cual buscare el nuevo "id" en el nuevo "equipo", ¿Como?
        //coloco la condicion del "nombre" y el "id_padre" de los datos originales
        //mas el "id" del equipo nuevo
        $datos_partes_obtenida = Partes::select(array('id'))
        ->where('nombre', '=', $datos_partes_original['nombre'])
        ->where('id_padre', '=', $datos_partes_original['id_padre'])
        ->where('id_equipos', '=', $id_equipo_new)
        ->get()
        ->first()
        ->toArray();

        //creo el array con el "id" el cual se va a modificar y su respectivo "id_padre"
        $array = array(
            'id' => $datos_partes_nuevos[$clave]['id'],
            'id_padre' => $datos_partes_obtenida['id'],
        );

        //agrego el arreglo a la variable "$ids"
        array_push($ids, $array);
    }
}

//recorro lo que contiene la variable "$ids" y modifico el "id_padre"
foreach($ids as $clave => $elemento){
    $id = $ids[$clave]['id'];
    $result_edit = Partes::findOrFail($id);
    $campos_edit = [
        'id_padre' => $ids[$clave]['id_padre'],
    ];
    $result_edit->update($campos_edit);
}
    
answered by 12.08.2017 / 08:59
source
0

I really think it's a very manual process what you try to do and I even wonder (without knowing the details of the project) if the database structure could have been designed differently, in any case Laravel does not offer any direct way to regenerate these relationships when copying.

A different way and a little more "Laravel" to copy the models would be with the method replicate() , and with dissociate() and associate() to join it to the new team, I think something like this (without testing):

$datos_partes = Partes::select(array('nombre', 'id_equipos', 'id_padre', 'status'))
    ->where('id_equipos', '=', $req->id)
    ->get();

foreach($datos_partes as $parte) {
    $nuevaParte = $parte->replicate();

    // $result en este caso contiene el modelo de Equipo
    // asumo que la relación se llama equipo
    $nuevaParte->equipo()->associate($result);

    $nuevaParte->push();
}

So what you are doing now, in terms of reassociating it with the new "father", would look for how to generate a temporary arrangement where you "map" old and new parents:

$nuevosIds = [];

foreach ($datos_partes as $parte) {
    $nuevaParte = $parte->replicate();

    $nuevaParte->equipo()->associate($result);

    $nuevaParte->save();

    // pueden haber errores aquí, pero entiendes la idea
    $nuevosIds[$parte->id] = $nuevaParte->id;

    if (isset($nuevosIds[$nuevaParte->id_padre])) {

        // reasociar al modelo correspondiente
        $nuevoPadre = Partes::find($nuevosIds[$nuevaParte->id_padre]);

        // asumiendo que la relación con si mismo se llame padre
        $nuevaParte->padre()->associate($nuevoPadre);
        $nuevaParte->save();

        // si lo anterior no funciona lo puedes hacer manual
        // $nuevaParte->id_padre = $nuevosIds[$nuevaParte->id_padre];
    }
}
    
answered by 10.08.2017 в 15:59