web-dev-qa-db-ja.com

Laravel、sync()-配列を同期し、追加のピボットフィールドを渡す方法は?

公式のLaravelドキュメントには、sync()関数でこれがあります:

$user->roles()->sync( array( 1, 2, 3 ) );

他のピボットテーブル値を特定のIDに関連付けることもできます。

$user->roles()->sync( array( 1 => array( 'expires' => true ) ) );

後者の例では、1つのピボット行のみが追加されています。私が理解していないのは、同期する行が複数ある場合、他のピボットテーブルレコードをどのように関連付けることができるのですか?

前もって感謝します。

カスタムピボットデータとともに複数のモデルをsyncするには、これが必要です。

$user->roles()->sync( array( 
    1 => array( 'expires' => true ),
    2 => array( 'expires' => false ),
    ...
));

すなわち。

sync( array( 
    related_id => array( 'pivot_field' => value ),
    ...
));

編集する

コメントに答える:

$speakers  = (array) Input::get('speakers'); // related ids
$pivotData = array_fill(0, count($speakers), ['is_speaker' => true]);
$syncData  = array_combine($speakers, $pivotData);

$user->roles()->sync($syncData);
106
Jarek Tkaczyk

これは私のために働く

foreach ($photos_array as $photo) {

    //collect all inserted record IDs
    $photo_id_array[$photo->id] = ['type' => 'Offence'];  

}

//Insert into offence_photo table
$offence->photos()->sync($photo_id_array, false);//dont delete old entries = false
12
The Dude

次の特性をプロジェクトに追加し、特性としてモデルクラスに追加します。これは、複数のピボットを使用する機能が追加されるため便利です。おそらく誰かがこれを少しきれいにして改善することができます;)

namespace App\Traits;

trait AppTraits
{
    /**
     * Create pivot array from given values
     *
     * @param array $entities
     * @param array $pivots
     * @return array combined $pivots
     */
    public function combinePivot($entities, $pivots = [])
    {
        // Set array
        $pivotArray = [];
        // Loop through all pivot attributes
        foreach ($pivots as $pivot => $value) {
            // Combine them to pivot array
            $pivotArray += [$pivot => $value];
        }
        // Get the total of arrays we need to fill
        $total = count($entities);
        // Make filler array
        $filler = array_fill(0, $total, $pivotArray);
        // Combine and return filler pivot array with data
        return array_combine($entities, $filler);
    }
}

型:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Example extends Model
{
    use Traits\AppTraits;
    // ...
}

使用法:

// Get id's
$entities = [1, 2, 3];
// Create pivots
$pivots = [
    'price' => 634,
    'name'  => 'Example name',
];
// Combine the ids and pivots
$combination = $model->combinePivot($entities, $pivots);
// Sync the combination with the related model / pivot
$model->relation()->sync($combination);
1
Tom van Tilburg

取り付け/取り外し

Eloquentは、関連モデルの操作をより便利にするためのいくつかの追加のヘルパーメソッドも提供します。たとえば、ユーザーが多くのロールを持つことができ、ロールが多くのユーザーを持つことができるとします。モデルを結合する中間テーブルにレコードを挿入してユーザーにロールをアタッチするには、アタッチメソッドを使用します。

$user = App\User::find(1);

$user->roles()->attach($roleId);

リレーションシップをモデルにアタッチするとき、中間テーブルに挿入される追加データの配列を渡すこともできます。

$user->roles()->attach($roleId, ['expires' => $expires]);

古いロールを削除し、現在アタッチしている新しいロールのみを保持する場合も、同期を使用できます。

$user->roles()->sync([1 => ['expires' => $expires], 2 => ['expires' => $expires]);

デフォルトの動作は、2番目の引数として「false」を渡すことで変更できます。これにより、既存のロールに影響を与えることなく、ID 1、2、3のロールがアタッチされます。

このモードでは、syncはattachメソッドと同様に動作します。

$user->roles()->sync([1 => ['expires' => $expires], 2 => ['expires' => $expires], false);

リファレンス: https://laravel.com/docs/5.4/eloquent-relationships

1
Miguel Trevino

単にappend your fieldsとそのvaluesを要素に追加するだけです:

$user->roles()->sync([
   1 => ['F1' => 'F1 Updated']
]);
0
X 47 48 - IR