وابستگی حذف
ماژول DeleteDependency برای جلوگیری از حذف رکوردهایی استفاده میشود که در بخشهای دیگر سیستم وابستگی دارند یا بر اساس یک شرط نباید حذف شوند.
با استفاده از این ماژول میتوان قبل از حذف رکورد، وابستگیهای relation، شرطهای سفارشی و ruleهای مبتنی بر flag را بررسی کرد و پیام مناسب به کاربر نمایش داد.
استفاده در مدل
برای فعالسازی قابلیت بررسی وابستگی حذف، trait زیر را به مدل اضافه کنید:
use Dornica\Foundation\DeleteDependency\Traits\HasDeleteDependency;
سپس وابستگیهای مدل را در متد deleteDependencies تعریف کنید.
<?php
namespace Modules\Shop\app\Models;
use Dornica\Foundation\DeleteDependency\DTO\DeleteDependency;
use Dornica\Foundation\DeleteDependency\Traits\HasDeleteDependency;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
use HasDeleteDependency;
public function deleteDependencies(): array
{
return [
DeleteDependency::relation('products')
->label('shop::messages.products'),
DeleteDependency::condition(fn() => !$this->is_locked)
->label('shop::messages.locked_record'),
];
}
public function products()
{
return $this->hasMany(Product::class);
}
public function children()
{
return $this->hasMany(self::class, 'parent_id');
}
}
تعریف وابستگیها
وابستگی بر اساس relation
اگر relation داده داشته باشد، حذف رکورد مسدود میشود.
DeleteDependency::relation('products')
->label('shop::messages.products');
در این مثال، اگر relation با نام products دارای رکورد باشد، مدل قابل حذف نیست.
ruleهای مبتنی بر flag
برای شرایط سادهتر یا flagهای مدل، میتوان از DeleteFlagRule استفاده کرد:
DeleteDependency::condition(fn() => !$this->is_locked)->label('shop::messages.locked_record'),
DeleteDependency::condition(fn() => $this->can_delete),
ورودی condition میتواند bool یا Closure باشد.
تنظیمات پیشفرض
در فایل config/dornica-app.php میتوان حالت پیشفرض نمایش پیام خطای وابستگی حذف را تعیین کرد:
'delete_dependency' => [
'default_mode' => 'general', // first | all | general
'general_message' => 'foundation::messages.delete_not_allow_cause_dependencies',
],
| مقدار | توضیح |
|---|---|
first | فقط اولین وابستگی مسدودکننده در پیام نمایش داده میشود. |
all | تمامی وابستگیهای مسدودکننده در پیام نمایش داده میشوند. |
general | یک پیام عمومی از کلید message نمایش داده میشود (بدون ذکر نام وابستگیها). |
اگر در زمان فراخوانی توابع، حالت نمایش پیام توسط توسعهدهنده مشخص شده باشد، همان مقدار استفاده میشود. در غیر این صورت، مقدار پیشفرض تعریفشده در تنظیمات ملاک قرار میگیرد.
بررسی پیام حذف
برای دریافت پیام خطای حذف:
// استفاده از حالت پیشفرض تنظیمات
if ($message = $category->getDeleteErrorMessage()) {
return back()->withFlash($message, 'error');
}
// تعیین حالت بهصورت دستی (override تنظیمات)
if ($message = $category->getDeleteErrorMessage(DeleteDependencyMode::FIRST)) {
return back()->withFlash($message, 'error');
}
حالتهای قابل استفاده:
| حالت | توضیح |
|---|---|
DeleteDependencyMode::FIRST | اولین وابستگی یا rule مسدودکننده را در پیام نمایش میدهد. |
DeleteDependencyMode::ALL | همه وابستگیها و ruleهای مسدودکننده را در پیام نمایش میدهد. |
DeleteDependencyMode::GENERAL | پیام عمومی تنظیمشده در config('dornica-app.delete_dependency.general_message') را نمایش میدهد. |
null (پیشفرض) | از مقدار تنظیمشده در config('dornica-app.delete_dependency.default_mode') استفاده میشود. |
متدهای کاربردی
$category->hasDependencies();
$category->getBlockingRelation();
$category->getAllBlockingRelations();
$category->hasDeleteFlagBlocks();
$category->getBlockingFlagRule();
$category->getAllBlockingFlagRules();
$category->getAllBlockingLabels();
$category->canBeDeleteOrFail();
$category->deletionBlockMessage();
اگر در زمان حذف، وابستگی فعال وجود داشته باشد، متد canBeDeleteOrFail یک exception از نوع DeletionGuardException پرتاب میکند.
attribute قابل حذف بودن
trait به صورت پیشفرض attribute با نام deletable را به مدل append میکند. حالت نمایش پیام از تنظیمات پیشفرض خوانده میشود.
$category->deletable->canDelete();
$category->deletable->getMessage();
DeleteProtection Facade
این ماژول یک singleton با نام delete-protection و یک facade برای استفاده مستقیم فراهم میکند.
use Dornica\Foundation\DeleteDependency\Facades\DeleteProtection;
DeleteProtection::check($category);
DeleteProtection::message($category);
// تعیین حالت نمایش پیام
DeleteProtection::message($category, DeleteDependencyMode::FIRST);
خروجی متدها:
| متد | خروجی | توضیح |
|---|---|---|
check | bool | مشخص میکند مدل قابل حذف است یا نه. |
message | string یا null | پیام مسدود شدن حذف را برمیگرداند. حالت پیشفرض از config خوانده میشود. |
حذف محافظتشده
برای اجرای حذف از طریق سرویس داخلی:
use Dornica\Foundation\DeleteDependency\Enums\DestroyType;
use Dornica\Foundation\DeleteDependency\Facades\DeleteProtection;
$service = DeleteProtection::destroy()
->model(Category::class)
->target([1, 2, 3])
->atomic()
->execute();
$service->hasError();
$service->getErrors();
$service->getMessage();
حالتهای حذف:
| حالت | توضیح |
|---|---|
DestroyType::ATOMIC | اگر حذف یکی از رکوردها خطا داشته باشد، کل عملیات rollback میشود. |
DestroyType::PARTIAL | رکوردهای قابل حذف حذف میشوند و خطاهای رکوردهای ناموفق جمعآوری میشود. |
متدهای اصلی builder:
| متد | توضیح |
|---|---|
model | کلاس مدل مورد نظر برای حذف را مشخص میکند. |
target | رکورد، شناسه یا آرایهای از شناسهها را مشخص میکند. |
atomic | حذف را در حالت atomic اجرا میکند. |
partial | حذف را در حالت partial اجرا میکند. |
type | نوع حذف را با enum مشخص میکند. |
execute | عملیات حذف را اجرا میکند و DestroyService برمیگرداند. |
همچنین میتوان نوع حذف را مستقیم با enum مشخص کرد:
$service = DeleteProtection::destroy(Category::class)
->target([1, 2, 3])
->type(DestroyType::PARTIAL)
->execute();
ن کات
- اگر هیچ وابستگی فعالی وجود نداشته باشد، خروجی
getDeleteErrorMessageبرابرnullاست. - ابتدا relationها بررسی میشوند و سپس ruleهای flag.
- ترتیب تعریف ruleها مهم است؛ در حالت
FIRSTاولین مورد مسدودکننده در پیام نمایش داده میشود. - این ماژول از event حذف مدل استفاده میکند، بنابراین حذف مستقیم از query builder مانند
Category::where(...)->delete()ممکن است event مدل را اجرا نکند. - حالت پیشفرض نمایش پیام از
config('dornica-app.delete_dependency.default_mode')خوانده میشود و در تمام متدها قابل override است.