【问题标题】:Laravel Many-To-Many sync() on multiple columnsLaravel 多列上的多对多同步()
【发布时间】:2021-12-21 05:26:33
【问题描述】:

我正在尝试执行以下操作:

我有 Targets 模型; 我有字段模型; 这两个是通过数据透视表的多对多关系; 我希望能够使用多列唯一或主列,并使用 sync() 更新数据透视表上的“金额”列。

查看图片。

目标表:

字段表:

数据透视表(理想情况下):

正如您在数据透视表上看到的那样,有“年”和“月”,我只需要能够“同步”或更新特定字段的特定年/月的金额。

当我使用 sync() 执行此操作时(不要介意“UserTarget::”。为了简化,假设它是“Target::”):

它使用最后一个数组项更新数据透视表,我得到了这个:

但它必须是这样的:

我的目标模型:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Models\TargetField;

class Target extends Model
{
    use HasFactory;

    protected $table = 'targets';

    public function fields()
    {
        // return $this->belongsToMany(
        //     RelatedModel, 
        //     pivot_table_name, 
        //     foreign_key_of_current_model_in_pivot_table, 
        //     foreign_key_of_other_model_in_pivot_table
        // );

        return $this->belongsToMany(
                'App\Models\Field',
                'target_field',
                'user_target_id',
                'user_target_field_id'
            )->withPivot(['year', 'month', 'amount', 'user_id']);
    }

}

字段模型:

<?php

命名空间 App\Models;

使用 Illuminate\Database\Eloquent\Factories\HasFactory; 使用 Illuminate\Database\Eloquent\Model;

类字段扩展模型 { 使用 HasFactory;

protected $table = 'fields';

public function targets()
{
    // return $this->belongsToMany(
    //     RelatedModel, 
    //     pivot_table_name, 
    //     foreign_key_of_current_model_in_pivot_table, 
    //     foreign_key_of_other_model_in_pivot_table
    // );

    return $this->belongsToMany(
            'App\Models\Target',
            'target_field',
            'user_target_field_id',
            'user_target_id'
        )->withPivot(['year', 'month', 'amount', 'user_id']);
}

}

我在枢轴模型中这样做:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class TargetField extends Model
{
    use HasFactory;

    // pivot table to get user target fields (many to many)
    protected $table = 'target_field';

    public $incrementing = false;

    protected $primaryKey = ['user_target_id','user_target_field_id','user_id','year','month'];

    protected $fillable = ['user_target_id','user_target_field_id','user_id','year','month'];

    /**
     * Set the keys for a save update query.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    protected function setKeysForSaveQuery($query)
    {
        $keys = $this->getKeyName();
        if(!is_array($keys)){
            return parent::setKeysForSaveQuery($query);
        }

        foreach($keys as $keyName){
            $query->where($keyName, '=', $this->getKeyForSaveQuery($keyName));
        }

        return $query;
    }

    /**
     * Get the primary key value for a save query.
     *
     * @param mixed $keyName
     * @return mixed
     */
    protected function getKeyForSaveQuery($keyName = null)
    {
        if(is_null($keyName)){
            $keyName = $this->getKeyName();
        }

        if (isset($this->original[$keyName])) {
            return $this->original[$keyName];
        }

        return $this->getAttribute($keyName);
    }

}

您对我可能做错的事情有任何想法或建议吗?

所以基本上我希望能够保存/更新数据透视表上的多行(年、月、user_id),这些行的值与“金额”列不同。

救命!

【问题讨论】:

    标签: laravel eloquent synchronization many-to-many


    【解决方案1】:

    您可以使用newPivotQuery 为数据透视表创建一个新的查询生成器。

    $userTaraget=UserTarget::find(1);
    // first delete old rows:
    $userTaraget->Fields()->newPivotQuery()->where('user_id',188)->delete();
    // then: insert new ones:
    $userTaraget->Fields()->newPivotQuery()->saveMany([['year'=>2021, 'month'=>3, 'amount'=>5, 'user_id'=>188],
    ['year'=>2020, ....]);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-10
      • 2015-02-14
      • 2021-07-22
      • 2021-01-13
      • 1970-01-01
      • 1970-01-01
      • 2021-10-31
      • 2017-08-26
      相关资源
      最近更新 更多