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
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();
}
Please or to participate in this conversation.