【问题标题】:Laravel, sync() - how to sync an array and also pass additional pivot fields?Laravel,sync() - 如何同步数组并传递额外的数据透视字段?
【发布时间】:2015-01-29 14:13:55
【问题描述】:

官方 Laravel 文档在 sync() 函数上有这个:

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

您还可以将其他数据透视表值与给定 ID 关联:

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

在后一个示例中,仅添加了一个数据透视行。我不明白的是,如果要同步的行不止一行,如何关联其他数据透视表记录?

提前致谢。

【问题讨论】:

  • 下面的答案并没有让我平静下来..你能发布你的解决方案吗?谢谢!
  • 好问题...所有教程都充满了基础知识。

标签: php laravel pivot eloquent sync


【解决方案1】:
    foreach ($request->exercise_id as $key => $exercise_id) {
        $data_plan[$exercise_id] = [
            'serie' => $request->serie[$key],
            'observation' => $request->observation[$key],
        ];
    }

【讨论】:

    【解决方案2】:

    如果您想为所有同步项目设置相同的枢轴值,现在可以使用->syncWithPivotValues($ids, $pivotValues) 方法。

    例如from the doc:

    $user->roles()->syncWithPivotValues([1, 2, 3], ['active' => true]);
    

    【讨论】:

      【解决方案3】:

      把它放在这里以防我以后忘记它并再次谷歌它。

      在我的情况下,我希望额外的列对每一行都有相同的数据

      其中 $syncData 是一个 ID 数组:

      $syncData = array_map(fn($locationSysid) => ['other_column' => 'foo'], array_flip($syncData));
      

      或不带箭头

      $syncData = array_map(function($locationSysid) {
            return ['ENTITY' => 'dbo.Cli_Core'];
         }, array_flip($syncData));
      

      (array_flip 表示我们使用 ID 作为数组的索引)

      【讨论】:

        【解决方案4】:

        为了sync 多个模型以及自定义数据透视数据,您需要这个:

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

        即。

        sync([
            related_id => ['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);
        

        【讨论】:

        • Jarek 但是如果我有例如$speakers = \Input::get( 'speakers' )(其中 $speakers 成为一个数组),然后想通过 $speakers=>array( 'is_speaker' => true) 怎么办?
        • 不是这样。您可以创建如上所示的同步数组。使用ids 作为键构建您的数组,或者在您的 HTML 表单中使用这种方式。
        • Jarek,我的 \Input::get('speakers') 正在返回一个 id 数组。会不会有这样的工作:$training->users()->sync( array( $speakers => array( 'is_speaker' => true ) ) )
        • @JarekTkaczyk 谢谢!评论的答案正是我想要的!
        • @JarekTkaczyk 看起来不错,但每个项目都会更新\插入一个单独的查询,这有点令人失望,因为它会影响性能。
        【解决方案5】:
        $data = array();
        foreach ($request->planes as $plan) {
         $data_plan = array($plan => array('dia' => $request->dia[$plan] ) );                
         array_push($data,$data_plan);    
        }
        $user->planes()->sync($data);
        

        【讨论】:

        • 在回答旧帖子时,如果您可以为您的回答提供一些上下文而不仅仅是代码,这将很有帮助,因为它可能对其他人更有用。
        • 见大卫雄鹿评论。此外,包括软件和/或系统和/或库版本;防止投票或删除答案的唯一方法。
        【解决方案6】:

        这对我有用

        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
        

        【讨论】:

        • 赞成这个,因为它又好又干净,而且我怀疑任何后续的开发人员都很容易理解和修改。
        • 您也可以将->sync($photo_id_array, false) 替换为->syncWithoutDetaching($photo_id_array)。也赞成,因为这是最优雅的解决方案。
        【解决方案7】:

        将以下特征添加到您的项目中,并将其作为特征附加到您的模型类中。这很有帮助,因为这增加了使用多个枢轴的功能。 可能有人可以清理一下并改进它;)

        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);
        

        【讨论】:

        • 我喜欢你的想法——最好把它变成可重复使用的东西,而不是在下次出现这个问题时复制——尽管我建议将它设为辅助函数,以便它可以在任何地方使用和任何型号。
        【解决方案8】:

        只需追加您的字段及其到元素:

        $user->roles()->sync([
           1 => ['F1' => 'F1 Updated']
        ]);
        

        【讨论】:

          【解决方案9】:

          附加/分离

          Eloquent 还提供了一些额外的辅助方法,使使用相关模型更加方便。例如,假设一个用户可以有很多角色,而一个角色可以有很多用户。要通过在连接模型的中间表中插入记录来将角色附加到用户,请使用 attach 方法:

          $user = App\User::find(1);
          
          $user->roles()->attach($roleId);
          

          将关系附加到模型时,您还可以传递要插入中间表的附加数据数组:

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

          如果您想删除旧角色并仅保留角色,您也可以使用同步 你现在附加的新的

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

          可以通过将“false”作为第二个参数来更改默认行为 争论。 这将附加 id 为 1,2,3 的角色,而不会影响现有的 角色。

          在这种模式下,同步的行为类似于附加方法。

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

          参考: https://laravel.com/docs/5.4/eloquent-relationships

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-05-08
            • 2023-04-06
            • 2015-05-29
            • 2018-01-18
            • 1970-01-01
            • 1970-01-01
            • 2021-10-25
            • 2019-08-20
            相关资源
            最近更新 更多