سلام! من آرش فدایی هستم و تو این قسمت از سری آموزشی لاراول ۱۲ قراره درباره مدلها و Eloquent، که قلب مدیریت دیتابیس در لاراول هست، صحبت کنیم. Eloquent یه ORM (Object-Relational Mapping) قدرتمنده که کار با دیتابیس رو مثل یه بازی ساده میکنه. تو این مقاله، یاد میگیرید چطور مدل بسازید، با دیتابیس ارتباط برقرار کنید و عملیات CRUD (ایجاد، خواندن، بهروزرسانی، حذف) رو انجام بدید. بریم شروع کنیم!
Eloquent: تجربه شخصی من
وقتی اولین بار با Eloquent کار کردم، فکر میکردم کار با دیتابیس قراره کلی کوئری SQL پیچیده بخواد. اما Eloquent با سینتکس ساده و شیءگراش منو شگفتزده کرد. یه بار تو یه پروژه داشتم یه سیستم وبلاگ میساختم و با Eloquent تونستم تو چند خط کد، پستها و کامنتها رو مدیریت کنم. تو لاراول ۱۲، Eloquent حتی قویتر شده و قابلیتهایی مثل بهبودهای کوئری و بهینهسازیهای عملکردی بهش اضافه شده. حالا بیاید با یه مثال عملی شروع کنیم.
پیشنیازها
قبل از شروع، مطمئن بشید که دیتابیستون رو تو فایل .env تنظیم کردید (مثل چیزی که تو قسمت اول گفتیم). همچنین، یه جدول توی دیتابیس نیاز داریم. برای این آموزش، فرض میکنیم یه جدول posts برای مدیریت پستهای وبلاگ داریم.
ساخت مدل و Migration
اول بیاید یه مدل و Migration برای پستها بسازیم. تو ترمینال این دستور رو اجرا کنید:
php artisan make:model Post -m
این دستور دو تا فایل میسازه:
-
مدل Post تو پوشه app/Models/Post.php
-
فایل Migration تو پوشه database/migrations
فایل Migration رو باز کنید (مثلاً database/migrations/xxxx_create_posts_table.php) و اینجوری اصلاحش کنید:
<?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('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('posts');
}
};
حالا Migration رو اجرا کنید تا جدول ساخته بشه:
php artisan migrate
یه تجربه از خودم: یه بار فراموش کردم migrate رو اجرا کنم و کلی دنبال خطای “جدول پیدا نشد” گشتم. همیشه بعد از ساخت Migration، یادتون باشه این دستور رو بزنید!
کار با مدل Post
مدل Post به صورت پیشفرض به جدول posts وصل میشه. فایل app/Models/Post.php باید چیزی شبیه این باشه:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $fillable = ['title', 'content'];
}
اینجا fillable مشخص میکنه که کدوم فیلدها میتونن به صورت انبوه پر بشن (Mass Assignment). من خودم همیشه fillable رو تنظیم میکنم تا از مشکلات امنیتی جلوگیری کنم.
عملیات CRUD با Eloquent
بیاید یه کنترلر برای مدیریت پستها بسازیم:
php artisan make:controller PostController --resource
این دستور یه کنترلر با متدهای CRUD آماده میسازه. حالا بیاید چند تا عملیات اصلی رو با Eloquent پیاده کنیم.
۱. ایجاد پست (Create)
تو PostController متد store رو اینجوری اصلاح کنید:
public function store(Request $request)
{
$post = Post::create([
'title' => $request->title,
'content' => $request->content,
]);
return redirect()->route('posts.index')->with('success', 'پست با موفقیت ایجاد شد!');
}
و تو فایل routes/web.php مسیر مربوط به ذخیره پست رو تعریف کنید:
use App\Http\Controllers\PostController;
Route::resource('posts', PostController::class);
اینجا Post::create یه پست جدید تو دیتابیس ذخیره میکنه. من تو یه پروژه از این روش برای ذخیره فرمهای کاربر استفاده کردم و خیلی سریع بود.
۲. خواندن پستها (Read)
برای نمایش لیست پستها، متد index رو اینجوری تنظیم کنید:
public function index()
{
$posts = Post::all();
return view('posts.index', compact('posts'));
}
حالا یه ویو تو resources/views/posts/index.blade.php بسازید:
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<title>لیست پستها</title>
</head>
<body>
<h1>لیست پستها</h1>
<ul>
@foreach ($posts as $post)
<li>{{ $post->title }}: {{ $post->content }}</li>
@endforeach
</ul>
</body>
</html>
این کد همه پستها رو از دیتابیس میخونه و تو یه لیست نمایش میده. یه بار من فراموش کردم ویو رو درست بذارم و صفحه سفید دیدم. همیشه مطمئن شید مسیر ویو درست باشه!
۳. بهروزرسانی پست (Update)
برای ویرایش پست، متد update رو اینجوری بنویسید:
public function update(Request $request, Post $post)
{
$post->update([
'title' => $request->title,
'content' => $request->content,
]);
return redirect()->route('posts.index')->with('success', 'پست با موفقیت بهروزرسانی شد!');
}
اینجا Eloquent به صورت خودکار پست رو با ID مشخص پیدا میکنه و آپدیتش میکنه. من تو یه پروژه داشتم فرم ویرایش میساختم و این روش کلی تو وقتم صرفهجویی کرد.
۴. حذف پست (Delete)
برای حذف پست، متد destroy رو اینجوری تنظیم کنید:
public function destroy(Post $post)
{
$post->delete();
return redirect()->route('posts.index')->with('success', 'پست با موفقیت حذف شد!');
}
این کد پست رو از دیتابیس حذف میکنه. یه تجربه از خودم: یه بار به اشتباه یه middleware روی مسیر حذف نزاشتم و کاربرا تونستن پستهای همدیگه رو حذف کنن! همیشه برای عملیات حساس مثل حذف، از middleware مثل auth استفاده کنید.
کوئریهای پیشرفته با Eloquent
Eloquent فقط برای CRUD ساده نیست. بیاید چند تا کوئری پیشرفتهتر رو امتحان کنیم.
فیلتر کردن پستها
فرض کنید میخوایم فقط پستهایی که عنوانشون شامل کلمه “لاراول” هست رو نشون بدیم:
$posts = Post::where('title', 'like', '%لاراول%')->get();
یا مثلاً پستهای جدیدتر از یه تاریخ خاص:
$posts = Post::where('created_at', '>', now()->subDays(7))->get();
من تو یه پروژه داشتم یه داشبورد میساختم و از این کوئریها برای فیلتر کردن دادهها استفاده کردم. خیلی حس خوبیه وقتی با چند خط کد میتونید دادههای پیچیده رو فیلتر کنید!
مرتبسازی و محدود کردن
برای گرفتن ۵ پست آخر به ترتیب تاریخ:
$posts = Post::orderBy('created_at', 'desc')->take(5)->get();
این کد ۵ پست آخر رو به ترتیب نزولی (جدید به قدیم) برمیگردونه. من از این روش تو یه وبلاگ برای نمایش “آخرین پستها” استفاده کردم.
نکات تکمیلی
-
روابط (Relationships): Eloquent امکان تعریف روابط مثل one-to-many یا many-to-many رو داره. تو قسمتهای بعدی درباره روابط (مثل پست و کامنتها) بیشتر صحبت میکنیم.
-
اشکالزدایی: اگه کوئریتون کار نکرد، از dd($posts) یا Log::debug($posts) استفاده کنید. من خودم بارها با این روش مشکلاتم رو پیدا کردم.
-
لاراول ۱۲ و بهبودها: تو نسخه ۱۲، Eloquent کوئریهای پیچیده رو سریعتر اجرا میکنه و ابزارهای بهتری برای دیباگ داره. مثلاً میتونید از explain() برای تحلیل کوئریها استفاده کنید.
قسمت بعدی قراره درباره ویوها و Blade صحبت کنیم که چطور میتونید صفحات پویا و زیبا بسازید. اگه سوالی دارید یا جایی گیر کردید، تو کامنتها بپرسید. من همیشه از بازخوردهای شما کلی چیز جدید یاد میگیرم!
تا قسمت بعدی، موفق باشید!
