0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Laravel 1対多・多対多の更新はsync()

0
Posted at

LaravelのEloquent ORMはリレーションを非常に簡単に扱えますが、「1対多」や「多対多」の関連データをフォームから受け取って登録・更新する処理は、意外と面倒に感じることがあります。特に、チェックボックスで選択されたカテゴリIDを中間テーブルに保存するようなケースです。

「既存の関連を全部消して、新しいのを登録し直す?」「いや、差分だけ計算して追加・削除?」

そんな悩みを一発で解決してくれるのが、今回ご紹介する sync() メソッドです。この記事では、SEOキーワード「Laravel 1対多 更新」で検索してたどり着いたあなたにも、sync() の圧倒的な利便性をお伝えします。

「Laravel 1対多 更新」で検索されたかもしれませんが、sync() メソッドが本領を発揮するのは、実は「多対多 (belongsToMany)」リレーションシップです。

`sync()` メソッドはなぜこんなに便利なのか?

結論から言うと、sync() は「中間テーブルの状態を、渡した配列と全く同じ状態に同期してくれる」からです。

例えば、ある商品 (ID: 1) に関連するカテゴリIDを [1, 3, 5] にしたい場合を考えます。

従来の面倒な処理

sync() を使わない場合、以下のような複雑な処理が必要でした。

// 1. フォームから新しいカテゴリIDの配列を取得
$newCategoryIds = $request->input('category_list', []); // 例: [1, 3, 5]
// 2. 現在の商品を取得
$product = Product::find(1);
// 3. 現在関連付いているカテゴリIDを取得
$currentCategoryIds = $product->categories()->pluck('id')->toArray(); // 例: [1, 2, 4]
// 4. 削除すべきIDを計算 (現在にあって、新しいにない)
$detachIds = array_diff($currentCategoryIds, $newCategoryIds); // [2, 4]
// 5. 追加すべきIDを計算 (新しいにあって、現在にない)
$attachIds = array_diff($newCategoryIds, $currentCategoryIds); // [3, 5]
// 6. 削除実行
if (!empty($detachIds)) {
$product->categories()->detach($detachIds);
}
// 7. 追加実行
if (!empty($attachIds)) {
$product->categories()->attach($attachIds);
}

差分を計算して、detach() (削除) と attach() (追加) を呼び分ける…。非常に面倒ですね。

`sync()` を使った場合の処理

これが sync() を使うと、たった1行になります。

魔法の1行:

$product = Product::find(1);
$newCategoryIds = $request->input('category_list', []); // 例: [1, 3, 5]

// これだけ!
$product->categories()->sync($newCategoryIds);

この1行で、Laravelは裏側で以下の処理を自動的に実行してくれます。

  • 渡された配列 [1, 3, 5] に含まれていない既存の関連 (例: ID 2, 4) を中間テーブルから削除 (detach) します。
  • 渡された配列 [1, 3, 5] のうち、まだ中間テーブルに存在しない関連 (例: ID 3, 5) を追加 (attach) します。
  • 渡された配列 [1, 3, 5] のうち、すでに存在する関連 (例: ID 1) はそのまま保持します。

詳しくはこちら>>
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?