Laravel 多列上的多对多同步()
Posted
技术标签:
【中文标题】Laravel 多列上的多对多同步()【英文标题】:Laravel Many-To-Many sync() on multiple columns 【发布时间】: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),这些行的值与“金额”列不同。
救命!
【问题讨论】:
【参考方案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, ....]);
【讨论】:
以上是关于Laravel 多列上的多对多同步()的主要内容,如果未能解决你的问题,请参考以下文章