پیادهسازی مدلهای قابل مرتبسازی
مقدمه
این راهنما نحوه پیادهسازی مدلهای قابل مرتبسازی در برنامه Laravel شما را توضیح میدهد، که به شما امکان میدهد به راحتی ترتیب رکوردها را در پایگاه داده خود مدیریت کنید. قابلیت مرتبسازی بر روی یک زیرساخت قوی ساخته شده است که به طور خودکار موقعیت رکوردها را مدیریت میکند.
پیادهسازی رابط قابل مرتبسازی به مدلهای شما اجازه میدهد به طور خودکار مرتب شوند، که ایجاد رابطهای کشیدن و رها کردن و حفظ مرتبسازی یکنواخت در سراسر برنامه شما را آسان میکند.
مراحل پیادهسازی
مرحله 1: پیادهسازی رابط و Trait
ابتدا، رابط SortableEntity را پیادهسازی کنید و trait HasSorting را به مدل خود اضافه کنید:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Services\SortOrder\Contracts\SortableEntity;
use App\Services\SortOrder\Traits\HasSorting;
class YourModel extends Model implements SortableEntity
{
use HasSorting;
// ویژگیها و متدهای مدل شما...
}
مرحله 2: پیکربندی ستون مرتبسازی (اختیاری)
اگر نام ستون مرتبسازی شما با پیشفرض order متفاوت است، متد sortingColumnName را بازنویسی کنید:
- پیکربندی پیشفرض
- نام ستون سفارشی
// اگر از 'order' به عنوان ستون مرتبسازی استفاده میکنید، نیازی به بازنویسی نیست
// پیادهسازی پیشفرض به این صورت است:
public function sortingColumnName(): string
{
return 'order';
}
با پیکربندی پیشفرض، سیستم از ستون order برای مرتبسازی استفاده خواهد کرد.
public function sortingColumnName(): string
{
return 'position'; // یا هر نام ستون دیگر مانند 'sort_order'، 'sequence' و غیره.
}
این به سیستم میگوید از نام ستون سفارشی شما برای عملیات مرتبسازی استفاده کند.
مطمئن شوید که جدول شما ستون مناسب (یا order یا نام ستون سفارشی شما) را به عنوان یک عدد صحیح در مهاجرت خود تعریف کرده است:
$table->integer('order')->default(0);
مرحله 3: تعریف محدوده مرتبسازی (اختیاری)
اگر نیاز دارید مرتبسازی را به گروههای خاصی از رکوردها محدود کنید (مثلاً، فقط آیتمها را در همان دسته مرتب کنید)، متد baseSortQuery را بازنویسی کنید:
- محدوده پیشفرض
- محدوده بر اساس دستهبندی
- محدوده پیچیده
// اگر همه رکوردها را با هم مرتب میکنید، نیازی به بازنویسی نیست
// پیادهسازی پیشفرض به این صورت است:
public function baseSortQuery(): Builder
{
return $this->newQuery();
}
این همه رکوردهای مدل را با هم مرتب خواهد کرد.
public function baseSortQuery(): Builder
{
return $this->newQuery()
->where('category_id', $this->category_id);
}
این اطمینان میدهد که آیتمها فقط در دستهبندیهای مربوطه خود مرتب میشوند.
public function baseSortQuery(): Builder
{
return $this->newQuery()
->where('category_id', $this->category_id)
->where('is_active', true)
->where('user_id', auth()->id());
}
میتوانید محدودههای مرتبسازی پیچیده با شرایط متعدد تعریف کنید.
ویژگیهای موجود
پس از پیادهسازی رابط و trait قابل مرتبسازی، مدل شما قابلیتهای زیر را خواهد داشت:
1. مرتبسازی خودکار رکوردهای جدید
رکوردهای جدید به طور خودکار موقعیت بعدی موجود در محدوده مرتبسازی خود را دریافت میکنند.
// رکورد جدید در انتهای لیست قرار خواهد گرفت
$item = YourModel::create([
'name' => 'آیتم جدید',
'category_id' => 1
]);
// نیازی به تنظیم دستی ترتیب نیست - به طور خودکار مدیریت میشود
2. تغییر ترتیب آیتمها
میتوانید به راحتی موقعیت آیتمها را تغییر دهید:
// حرکت یک آیتم یک موقعیت به بالا
$item->moveUp();
// حرکت یک آیتم یک موقعیت به پایین
$item->moveDown();
// حرکت یک آیتم به موقعیت خاص
$item->moveTo(3);
// حرکت یک آیتم به اولین موقعیت
$item->moveToStart();
// حرکت یک آیتم به آخرین موقعیت
$item->moveToEnd();
3. مرتبسازی مجدد خودکار پس از حذف
وقتی یک رکورد حذف میشود، سیستم به طور خودکار آیتمهای باقیمانده را برای حفظ موقعیتهای متوالی مرتب میکند.
// وقتی این آیتم حذف میشود، سایر آیتمها به طور خودکار مرتب میشوند
$item->delete();
4. پرسوجوهای مبتنی بر ترتیب
مدلهای خود را به ترتیب مرتبشده پرسوجو کنید:
// دریافت همه آیتمها به ترتیب مرتبشده
$items = YourModel::ordered()->get();
// ترکیب با سایر شرایط پرسوجو
$items = YourModel::where('is_active', true)
->ordered()
->get();
زیرساخت
سیستم مرتبسازی از یک الگوی observer استفاده میکند که به طور خودکار روی مدلهایی که رابط SortableEntity را پیادهسازی میکنند اعمال میشود. این observer موارد زیر را مدیریت میکند:
- تنظیم مقدار اولیه ترتیب برای رکوردهای جدید
- مرتبسازی مجدد رکوردها هنگامی که موقعیت یک آیتم تغییر میکند
- پاکسازی توالی ترتیب هنگامی که رکوردها حذف میشوند
نیازی به پیکربندی دستی observer نیست - به طور خودکار از طریق سیستم ارائهدهنده سرویس Laravel ثبت میشود.
مثال پیادهسازی
- تعریف مدل
- مهاجرت
- استفاده در کنترلر
- نمای Blade
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Services\SortOrder\Contracts\SortableEntity;
use App\Services\SortOrder\Traits\HasSorting;
class MenuItem extends Model implements SortableEntity
{
use HasSorting;
protected $fillable = [
'name',
'url',
'menu_id',
'is_active'
];
// بازنویسی برای مرتبسازی در همان منو
public function baseSortQuery(): Builder
{
return $this->newQuery()
->where('menu_id', $this->menu_id);
}
// رابطه با منو
public function menu()
{
return $this->belongsTo(Menu::class);
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::create('menu_items', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('url');
$table->foreignId('menu_id')->constrained()->onDelete('cascade');
$table->boolean('is_active')->default(true);
$table->integer('order')->default(0); // ستون مرتبسازی
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('menu_items');
}
};
<?php
namespace App\Http\Controllers;
use App\Models\MenuItem;
use App\Models\Menu;
use Illuminate\Http\Request;
class MenuItemController extends Controller
{
public function index(Menu $menu)
{
// دریافت آیتمهای منو به ترتیب مرتبشده
$items = $menu->menuItems()->ordered()->get();
return view('menu.items.index', compact('menu', 'items'));
}
public function reorder(Request $request, MenuItem $item)
{
$position = $request->input('position');
// حرکت آیتم به موقعیت درخواستی
$item->moveTo($position);
return response()->json(['success' => true]);
}
}
<div class="menu-items" data-sortable>
@foreach($items as $item)
<div class="menu-item" data-id="{{ $item->id }}">
<span class="handle">☰</span>
<span class="name">{{ $item->name }}</span>
<span class="url">{{ $item->url }}</span>
<div class="actions">
<button class="edit-btn">ویرایش</button>
<button class="delete-btn">حذف</button>
</div>
</div>
@endforeach
</div>
<script>
// مثال جاوااسکریپت برای مرتبسازی با کشیدن و رها کردن
document.addEventListener('DOMContentLoaded', function() {
// مقداردهی اولیه sortable با کتابخانه مورد نظر شما
// وقتی آیتم جابجا میشود، درخواست AJAX برای بهروزرسانی موقعیت ارسال کنید
function updatePosition(itemId, newPosition) {
fetch(`/menu-items/${itemId}/reorder`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content
},
body: JSON.stringify({ position: newPosition })
});
}
});
</script>
نتیجهگیری
پیادهسازی مدلهای قابل مرتبسازی با استفاده از رابط SortableEntity و trait HasSorting یک پایه قوی برای مدیریت رکوردهای مرتبشده در برنامه Laravel شما فراهم میکند. این رویکرد ایجاد لیستهای قابل مرتبسازی، رابطهای کشیدن و رها کردن، و هر ویژگی که نیاز به حفظ ترتیب خاصی از رکوردها دارد را ساده میکند.
با استفاده از قابلیتهای مرتبسازی خودکار، میتوانید بر روی ساخت ویژگیهای منحصر به فرد برنامه خود تمرکز کنید، به جای نگرانی درباره پیچیدگیهای حفظ ترتیب رکوردها.