在多对多关系 laravel4 的情况下更新数据透视表

Posted

技术标签:

【中文标题】在多对多关系 laravel4 的情况下更新数据透视表【英文标题】:update pivot table in case of many to many relation laravel4 【发布时间】:2013-03-15 07:35:31 【问题描述】:

我最近开始使用 Laravel4。在多对多关系的情况下,我在更新数据透视表数据时遇到了一些问题。

情况是: 我有两个表:ProductProductType。 它们之间的关系是多对多。 我的模特是

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 的情况下更新数据透视表的主要内容,如果未能解决你的问题,请参考以下文章

Sequelize 查询在多对多关系中显示附加数据

在多对多 SQL 表中查找数据关系或图形

如何在不更新具有多对多关系的子实体的情况下保留父实体?

Laravel 4:具有额外关系的多对多

在多对多关系对象django的对象中获取null

在多对多关系中删除正确