Reputation: 116
I want to a connect two tables with a relation. The tables gets updated but not as expected. In one case I get the same record 2 times , in other method I'm getting only one record with no data.
With the attach method i get two times the same record and each time i'm sending the same request it creates the same records as before.
With the sync method it only adds the last record from the loop. I think sync is the way to go, because it doesn't create new records when sending the same request.
// Network Model
public function accounts() {
return $this->belongsToMany('App\Account');
}
// Account Model
public function networks() {
return $this->belongsToMany('App\Models\Network')-
>withPivot('url');
}
// Updateprofile function in accounts controller
$accounts = $request->get('accounts');
foreach ($accounts as $key => $account) {
$accountModel = Account::where("id", "=", $account['id'])-
>first();
/*
Some other fields that get updated ...
*/
$networks =
Network::find(Helper::getValueOrDefault(AuthConst::NETWORK,
$account, []));
foreach ($account['network'] as $key => $network) {
$accountModel->networks()->sync($network, ['url' =>
$network['url'], 'network_id' => $network['id']]);
}
$accountModel->save();
}
DB structure
Accounts Table
ID | And some metafields
Network Table
ID | Name | slug
Account_network relation Table
ID | network_id | account_id | url
The request gives an array called network with one or more objects
array(2) {
[0]=>
array(2) {
["id"]=>
int(3)
["url"]=>
string(19) "http://facebook.com"
}
[1]=>
array(2) {
["id"]=>
int(2)
["url"]=>
string(18) "http://youtube.com"
}
}
I expect that this wil attached to the right account with two records added to the Account_network table.
ID | network_id | account_id | url
1 | 3 | 1| http://facebook.com
2 | 2 | 1| http://youtube.com
And i expect when sending the same request, it does nothing because the records already exists.
Upvotes: 0
Views: 264
Reputation: 18926
Sync()
will delete all the ids in the table there is not in the input of the method, if you just want to add an entry to the many to many relation. You can utilize the syncWithoutDetaching()
method.
foreach ($account['network'] as $key => $network) {
$accountModel->networks()->syncWithoutDetaching($network, ['url' =>
$network['url'], 'network_id' => $network['id']]);
}
Upvotes: 0
Reputation: 1452
Attach only adds a new record to the pivot table. Sync accepts an id or an array of ids, removes all records and inserts only those present in the sync method. It accepts a second parameter as a bool which allows you to prevent this removal or you can use a syncWithoutDetaching method. So you don't need a foreach with sync as it will not work as you have intended.
Upvotes: 2