在多对多关系 laravel4 的情况下更新数据透视表
Posted
技术标签:
【中文标题】在多对多关系 laravel4 的情况下更新数据透视表【英文标题】:update pivot table in case of many to many relation laravel4 【发布时间】:2013-03-15 07:35:31 【问题描述】:我最近开始使用 Laravel4。在多对多关系的情况下,我在更新数据透视表数据时遇到了一些问题。
情况是: 我有两个表:Product、ProductType。 它们之间的关系是多对多。 我的模特是
class Product extends Eloquent
protected $table = 'products';
protected $primaryKey = 'prd_id';
public function tags()
return $this->belongsToMany('Tag', 'prd_tags', 'prta_prd_id', 'prta_tag_id');
class Tag extends Eloquent
protected $table = 'tags';
protected $primaryKey = 'tag_id';
public function products()
return $this->belongsToMany('Product', 'prd_tags', 'prta_prd_id', 'prta_tag_id');
在向数据透视表prd_tags插入数据时,我做了:
$product->tags()->attach($tag->tagID);
但是现在我想更新此数据透视表中的数据,将数据更新到数据透视表的最佳方法是什么。 比方说,我想删除一些标签并为特定产品添加新标签。
【问题讨论】:
您是否阅读了文档中的信息?有帮助吗...four.laravel.com/docs/eloquent#working-with-pivot-tables @PhillSparks:是的,我已经阅读了这份文件。有一种称为同步的方法来执行此操作,它将分别采用一个 id 数组并插入和删除,但是如果我的数据透视表具有两个表的 id 以外的属性怎么办。同步方法应该采用对象数组而不是整数数组。 Eloquent 提倡一种简单的表格设计,其中您的数据透视表具有用于引用行的 ID 列。 Eloquent 并不是为了迎合其他数据库设计而设计的,因为有更全面的 ORM 解决方案可用。 【参考方案1】:老问题,但在 2013 年 11 月 13 日,updateExistingPivot 方法对多对多关系公开。这还没有在官方文档中。
public void updateExistingPivot(mixed $id, array $attributes, bool $touch)
--更新表中现有的数据透视记录。
自 2014 年 2 月 21 日起,您必须包含所有三个参数。
在你的情况下,(如果你想更新数据透视字段'foo')你可以这样做:
$product->tags()->updateExistingPivot($tag->tagID, array('foo' => 'value'), false);
如果您想触摸父时间戳,也可以将最后一个布尔值 false 更改为 true。
拉取请求:
https://github.com/laravel/framework/pull/2711/files
【讨论】:
太棒了。我希望更新官方文档以突出显示此方法。这应该被标记为正确答案。干杯! @haakym 不是错字,当时它没有返回任何内容。看起来它现在返回一个 int,大概是新的 id。我会编辑答案。谢谢。【参考方案2】:使用 laravel 5.0+ 时的另一种方法
$tag = $product->tags()->find($tag_id);
$tag->pivot->foo = "some value";
$tag->pivot->save();
【讨论】:
我必须使用$pivot->pivot->save();
来保存我的数据透视表。
这实际上是我认为最简单的解决方案。
如果使用这种方法会报错:Indirect modification of overloaded property has no effect
【参考方案3】:
我知道这是一个老问题,但如果您仍然对解决方案感兴趣,这里是:
假设您的数据透视表具有“foo”和“bar”作为附加属性,您可以这样做以将数据插入到该表中:
$product->tags()->attach($tag->tagID, array('foo' => 'some_value', 'bar'=>'some_other_value'));
【讨论】:
【参考方案4】:这是完整的例子:
$user = $this->model->find($userId);
$user->discounts()
->wherePivot('discount_id', $discountId)
->wherePivot('used_for_type', null)
->updateExistingPivot($discountId, [
'used_for_id' => $usedForId,
'used_for_type' => $usedForType,
'used_date_time' => Carbon::now()->toDateString(),
], false);
【讨论】:
【参考方案5】:从 Laravel 6 开始,您也可以使用 newPivotQuery()
,例如update()
同时有多个数据透视模型(数据库行)(使用Query\Builder::update()
语句)。
看起来像这样:
$someModel->someBelongsToManyRelation()
->wherePivotNotIn('some_column', [1, 2, 3])
->wherePivotNull('some_other_column')
->newPivotQuery()
->update(['some_other_column' => now()]);
或者没有 wherePivot 方法:
$someModel->someBelongsToManyRelation()
->newPivotQuery()
->whereNotIn('some_column', [1, 2, 3])
->whereNull('some_other_column')
->update(['some_other_column' => now()]);
【讨论】:
以上是关于在多对多关系 laravel4 的情况下更新数据透视表的主要内容,如果未能解决你的问题,请参考以下文章