使用复合键软删除/分离和恢复/附加关系

Bry*_*ynJ 14 laravel laravel-5 laravel-orm

我有两个模型,它们由一个具有复合键的关系连接 - 这些是产品和类别.我需要在所有表上使用软删除,以便在需要时可以恢复模型和关系.

在我的产品型号中,我有:

function categories()
{
    return $this->belongsToMany('App\Category', 'product_categories')->whereNull('product_categories.deleted_at')->withTimestamps();
}
Run Code Online (Sandbox Code Playgroud)

在我的分类模型中,我有:

function products()
{
    return $this->belongsToMany('App\Product', 'product_categories')->whereNull('product_categories.deleted_at')->withTimestamps();
}
Run Code Online (Sandbox Code Playgroud)

我在其他地方读到了关于链接whereNull方法的问题,因为查询$category->products->contains($product->id)会以其他方式返回软删除的关系.

我的问题是处理删除和恢复这些软删除关系的最佳方法是什么?例如,为了恢复,我试过:

$product->categories()->restore($category_id);
Run Code Online (Sandbox Code Playgroud)

上面产生了一个SQL错误,说出deleted_at字段是不明确的(因为它将类别表加入了product_categories).

更新 - 根本问题似乎是BelongsToMany类不支持软删除 - 因此附加,分离和同步都执行硬删除.覆盖这个课程的最佳方法是什么?

The*_*pha 5

基本上,只有一个deleted_at字段,而不是$product->categories()在两个(ProductCategory)模型中使用两个自定义(常用)方法,例如,您可以创建这样的特征:

// SoftDeletePC.php
trait SoftDeletePC {
    // SoftDelete
    public function softDeleteProductCategory($productId, $categoryId)
    {
        \DB::table('product_categories')
        ->where('product_id', $productId)
        ->where('category_id', $categoryId)
        ->update(['deleted_at' => \DB::raw('NOW()')]);
    }

    // Restore
    public function restoreProductCategory($productId, $categoryId)
    {
        \DB::table('product_categories')
        ->where('product_id', $productId)
        ->where('category_id', $categoryId)
        ->update(['deleted_at' => null]);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在两个模型中使用此特征use TraitProductCategory并从两个模型调用方法,例如:

// App/Product.php
class product extends Model {
    use SoftDeletePC;
}

// App/Category.php
class Category extends Model {
    use SoftDeletePC;
}
Run Code Online (Sandbox Code Playgroud)

所以,而不是使用这个:

Product->find(1)->categories()->restore(2);
Run Code Online (Sandbox Code Playgroud)

你可以使用这样的东西:

$product = Product->find(1);

$product->softDeleteProductCategory(1, 2); // Set timestamp to deleted_at

$product->restoreProductCategory(1, 2); // Set null to deleted_at
Run Code Online (Sandbox Code Playgroud)

希望这可能对你有用.