【问题标题】:Soft deleting a many-to-many relationship's pivot in Eloquent在 Eloquent 中软删除多对多关系的支点
【发布时间】:2014-09-27 04:19:04
【问题描述】:

有没有办法“软删除”多对多关系?我已经在我的数据透视表中添加了一个deleted_at 列,并且正在使用SoftDeletingTrait。但是当你detach这两个关系时,该行被完全删除。

我有表 clients、users 和 client_user。我希望不知何故,使用User::find($user_id)->detach($client_id) 不会真正删除数据透视行,而是将deleted_at 设置为当前时间戳。

然后在此之后继续,我不希望能够恢复软删除的项目。但是,此刻,即使我手动设置deleted_at的值,我仍然得到结果

【问题讨论】:

  • 我的问题是 - 你为什么要软删除它?这是您可以轻松取回的数据。软删除用作您不想丢失的数据的一种机制,即使它是被故意删除的 - 例如客户端和用户。
  • @Oddman,好吧,也许我给出的表格示例很糟糕。但我实际上拥有的是一个客户端创建然后将其发送给所有用户的请求表。一旦用户完成请求以记录人们提交请求的时间,我想然后软删除数据透视表
  • 我猜你需要的只是使用SoftDeletingTrait 的自定义数据透视模型 - 你试过了吗?
  • 是的,我这样做了,它仍然会删除该行。 SoftDeletingTrait 不适用于数据透视表。
  • @Kousha 是的,事实上,如果没有自定义关系对象处理你需要的所有东西,就没有办法做到这一点。

标签: laravel laravel-4 eloquent


【解决方案1】:
DB::table('client_user')
                ->where('client_id', $client->id)
                ->where('user_id', $user->id)
                ->update(array('deleted_at' => DB::raw('NOW()')));

【讨论】:

    【解决方案2】:
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Model;
    use Illuminate\Database\Eloquent\Relations\Relation;
    
    class User extend Model
    {
    
        public function clients(): Relation
        {
            return $this
                ->belongsToMany(
                    Client::class,
                    'client_user',
                    'user_id',
                    'client_id'
                )
                ->using(ClientUserPivot::class)
                ->wherePivot('deleted_at', null)
                // load pivot ID (otherwise deleted event won't fire)
                // load more pivot fileds if we need
                ->withPivot('id', 'is_enabled', 'extra') 
                ->withTimestamps();
        }
    
    }
    
    /* The Cilent model file, in a similar way */
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Model;
    use Illuminate\Database\Eloquent\Relations\Relation;
    
    class Client extend Model
    {
    
        public function users(): Relation
        {
            return $this
                ->belongsToMany(
                    User::class,
                    'client_user',
                    'client_id',
                    'user_id'
                )
                ->using(ClientUserPivot::class)
                ->wherePivot('deleted_at', null)
                // load pivot ID (otherwise deleted event won't fire)
                // load more pivot fileds if we need
                ->withPivot('id', 'is_enabled', 'extra') 
                ->withTimestamps();
        }
    
    }
    
    /* The Pivot file */
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Relations\Pivot;
    use Illuminate\Database\Eloquent\Relations\Relation;
    use Illuminate\Database\Eloquent\SoftDeletes;
    
    class ClientUserPivot extends Pivot
    {
        use SoftDeletes;
    
        public $incrementing = true;
    
        protected $table = 'client_user';
    
        protected $dates = ['deleted_at'];
    
        public function client(): Relation
        {
            return $this->belongsTo(Client::class);
        }
    
        public function user(): Relation
        {
            return $this->belongsTo(User::class);
        }
    }
    
    /////////////////////////
    // We can see that the Pivot class is extends Model class,
    // it just use the AsPivot trait, set the $incrementing = false,
    // and set the $guarded = [].
    
    // So, we can run the methods of Model in Pivot entity, such as @delete.
    // Working:
    $user = User::find(1);
    $client = $user->clients->firstWhere('id', $clientId);
    if ($client) {
        $client->pivot->delete();
    }
    
    // Last:
    // You may have seen that I added a 'is_enabled' field in the pivot table,
    // I think it may better than SoftDeletes.
    

    【讨论】:

    • 添加一些文本来展示你的代码是如何工作的。
    • 感谢这对我有用,没有 ->using() 位会引发错误
    【解决方案3】:

    是的,您可以在数据透视表上进行软删除,您只需为它们提供自己的 id 和时间戳。这样“SoftDeletingTrait”就可以工作了。这有点棘手,但它对我有用。 编辑:

    而且我也忘了提到你必须为数据透视表制作一个模型,正如上面有人告诉你的那样 =P 例如,你有一个信用额度,以及该信用额度的许多要求,用于许多credit_lines,但您想知道每行上的请求的状态,并且还从该信用额度中删除,而不是从其他信用额度中删除。

    Table
    credit_line
    id
    name
    capital
    [More columns]
    Table
    requirements (Documents and things that everybody uses)
    id
    name
    [More columns]
    
    Table (pivot)
    
    credit_line_has_requirements
    id <---- you need this...
    timestamps <---- also this
    status_id <---- declined, accepted etc... 
    reason <---- a text description of why you declined or acepted the requeriment...
    

    然后您使用该数据透视表为 CreditLineHasRequeriments 创建一个模型。

    抱歉英语不好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-18
      • 1970-01-01
      • 2013-06-25
      • 1970-01-01
      • 2015-04-03
      • 2013-01-05
      • 1970-01-01
      • 2019-06-13
      相关资源
      最近更新 更多