Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

rjruiz's avatar

How to save belongsToMany relationship in Laravel?

Within my form, I am trying to record the information that was used to make a piece. In the same form there is a relationship between PART and TOOL, it is a many-to-many relationship. Basically because a piece can have one or several tools, and the same tool can be in one or several pieces. So to register the tools that are used, I use a table with dynamic input fields through jquery.

In my form I enter the information in this way:

<div class="box box-primary">
            <div class="box-header with-border">
                <h3 class="box-title">Herramientas</h3>                
            </div>
            <div class="box-body">
                <table class="table table-striped table-bordered table-condensed table-hover" id="dynamicTable">  
                    <tr>
                        <th width="5%">Posición</th>
                        <th width="20%">Herramienta</th>                 
                        <th width="20%">Inserto</th>                 
                        <th width="20%">Calidad</th>                 
                        <th width="5%">Action</th>
                    </tr>
                    <tr>
                        <td><input type="text" name="addmore[0][position]"  placeholder="Posicion" class="form-control select2" /></td>                             
                        <td><input type="text" name="addmore[0][code_tool]"   placeholder="Herramienta" class="form-control" /></td>      
                        <td><input type="text" name="addmore[0][code_insert]"  placeholder="Inserto" class="form-control" /></td>  
                        <td><input type="text" name="addmore[0][quality]"  placeholder="Calidad" class="form-control" /></td>                      
                        <td><button type="button" name="add" id="add" class="btn btn-success"><i class="fa fa-plus-square"></i></button></td>                    
                    </tr>  
                </table> 
            </div>
        </div>

In my store method I am saving the relationship as follows:

public function store(Request $request)
    {

        if ($request->ajax()){
            try {
                //  Transacciones
                DB::beginTransaction();              

                // $this->authorize('create', new Piece);                               
                // dd($request->all());

                $addmore = $request->addmore;

                foreach($addmore as $add)
                {
                    $insert = Insert::create([
                        'code_insert' => $add['code_insert'],
                        'quality'     => $add['quality']
                    ]);   

                    $tools = $insert->tools()->create([
                       'position'   => $add['position'],
                       'code_tool'  => $add['code_tool'],                   
                       'insert_id'  => $insert->id                            
                    ]);                    
                }                    

                $gag     = Gag::create($request->all());
                $program = Program::create($request->all()); 

                $piece = $program->piece()->create([
                    'denomination' => $request['denomination'],
                    'code'         => $request['code'],
                    'time'         => $request['time'],
                    'part_piece'   => $request['part_piece'],
                    'gag_id'       => $gag->id
                ]);

                dd($tools);
                //asociar las herramientas a la pieza
                $piece->tools()->attach($tools);

                DB::commit();

            } catch (Exception $e) {
                // anula la transacion
                DB::rollBack();
            }
        }    
    }

Perform a test by registering a new part with their respective tools, for this example, my connecting rod piece with id = 8 must have 2 associated tools (id = 32 and id = 33), verifying this in my pivot table piece_tool I get the following:

piece_tool table:

id  | piece_id | tool_id
  9 |   8      |  33

What you really should get would be this:

id  | piece_id | tool_id
 9  |   8      |   32
 10 |   8      |   33

performing a verification here:

dd ($ tools);
 // associate the tools with the piece
 $ piece-> tools () -> attach ($ tools);

In the console I get the following:

Tool {#979
  #fillable: array:8 [
    0 => "insert_id"
    1 => "position"
    2 => "code_tool"
    3 => "type"
    4 => "category"
    5 => "status"
    6 => "description"
    7 => "reason"
  ]
  #connection: "mysql"
  #table: "tools"
  #primaryKey: "id"
  #keyType: "int"
  +incrementing: true
  #with: []
  #withCount: []
  #perPage: 15
  +exists: true
  +wasRecentlyCreated: true
  #attributes: array:6 [
    "position" => "02"
    "code_tool" => "ddd"
    "insert_id" => 36
    "updated_at" => "2020-02-08 00:35:19"
    "created_at" => "2020-02-08 00:35:19"
    "id" => 33
  ]
  #original: array:6 [
    "position" => "02"
    "code_tool" => "ddd"
    "insert_id" => 36
    "updated_at" => "2020-02-08 00:35:19"
    "created_at" => "2020-02-08 00:35:19"
    "id" => 33
  ]
  #changes: []
  #casts: []
  #dates: []
  #dateFormat: null
  #appends: []
  #dispatchesEvents: []
  #observables: []
  #relations: []
  #touches: []
  +timestamps: true
  #hidden: []
  #visible: []
  #guarded: array:1 [
    0 => "*"
  ]
}

I think there is a problem with this:

// associate the tools with the piece
$ piece-> tools () -> attach ($ tools);

I am not associating all the tools with their corresponding part. Can someone tell me how to correctly relate the tools to their part?

In my pivot table pice_tool only the last registered tool was associated, in this case I am missing to associate one more tool and I don't know why it is failed

0 likes
9 replies
a4ashraf's avatar

Hello @rjruiz

try this following code

$piece->tools()->syncWithoutDetaching([$tools]);

a4ashraf's avatar

Hello @rjruiz

follow this thread, here is the solution


$piece->tools()->syncWithoutDetaching([$comment->id]);

hopefully, it will work on your side because it is working on my site

rjruiz's avatar

hola @a4ashraf make the modification you just indicated, make a new test by creating a new piece with 2 different tools, when saving them in my pivot table piece_tool I only see the piece created associated with a single tool, (another one is missing) that is why I am Thinking that my problem is here:

 $addmore = $request->addmore;

                foreach($addmore as $add)
                {
                    $insert = Insert::create([
                        'code_insert' => $add['code_insert'],
                        'quality'     => $add['quality']
                    ]);  
                   
                    $tools = $insert->tools()->create([
                        'position'   => $add['position'],
                        'code_tool'  => $add['code_tool'],                   
                        'insert_id'  => $insert->id                            
                    ]);                
                    dd($tools);
                }

checking with dd($tools); i get this

#attributes: array:6 [
    "position" => "01"
    "code_tool" => "cod56"
    "insert_id" => 54
    "updated_at" => "2020-02-09 08:59:17"
    "created_at" => "2020-02-09 08:59:17"
    "id" => 50
  ]
  #original: array:6 [
    "position" => "01"
    "code_tool" => "cod56"
    "insert_id" => 54
    "updated_at" => "2020-02-09 08:59:17"
    "created_at" => "2020-02-09 08:59:17"
    "id" => 50
  ]

I enter two different tools, but I receive two identical tools. I think I'm close to being able to do it I need your help

a4ashraf's avatar
a4ashraf
Best Answer
Level 33

@rjruiz

there is the issue in $tool variable, you must extract last inserted ID from tools and store it into an array.

Now use syncWithoutDetaching method and attach these IDs with piece_tool table I have fixed the issue

Please change your Store method with this following code


 public function store(Request $request)
    {

         try {
            
            //  Transacciones
            DB::beginTransaction();      

            $addmore = $request->addmore;

            $arrTool = [];  // declare $arrTool

            foreach($addmore as $add)
            {
                $insert = Insert::create([
                    'code_insert' => $add['code_insert'],
                    'quality'     => $add['quality']
                ]);  
               
                $tools = $insert->tools()->create([
                    'position'   => $add['position'],
                    'code_tool'  => $add['code_tool'],                   
                    'insert_id'  => $insert->id                            
                ]);                
            
                $arrTool[] = $tools->id;  // create an array and store each id in it 
            }

            $gag = Gag::create($request->all());
            $program = Program::create($request->all()); 

            $piece = $program->piece()->create([
                'denomination' => $request['denomination'],
                'code'         => $request['code'],
                'time'         => $request['time'],
                'part_piece'   => $request['part_piece'],
                'gag_id'       => $gag->id
            ]);

            //asociar las herramientas a la pieza
            $piece->tools()->syncWithoutDetaching($arrTool);

            DB::commit();

        } catch (Exception $e) {
            // anula la transacion
            DB::rollBack();
        }
1 like
rjruiz's avatar

@a4ashraf Thanks for your answer later I try it and I comment the solution

rjruiz's avatar

@a4ashraf thanks for your answer I was able to save a piece with all its tools helped me solve my problem

Please or to participate in this conversation.