وقتی در یک پروژه Laravel با دیتابیس کار میکنیم، معمولاً اطلاعات جداول مختلف به یکدیگر وابسته هستند. برای مثال، هر کاربر میتواند چند سفارش داشته باشد، هر دستهبندی میتواند چند محصول داشته باشد و هر مقاله میتواند چندین دیدگاه داشته باشد.
این نوع ارتباط بین دادهها در طراحی دیتابیس با نام رابطه یک به چند یا One to Many شناخته میشود.
در Laravel و بهخصوص در ORM قدرتمند Eloquent، ایجاد و استفاده از این نوع رابطه بسیار ساده است. کافی است رابطه را در Modelهای مربوطه تعریف کنیم تا بتوانیم دادههای مرتبط را با کد تمیز و قابل فهم دریافت، ایجاد، ویرایش و حذف کنیم.
در این مقاله یاد میگیریم:
- One to Many چیست؟
- رابطه Parent و Child چگونه کار میکند؟
hasMany()چیست؟belongsTo()چیست؟- Foreign Key کجا قرار میگیرد؟
- چگونه دادههای مرتبط را دریافت کنیم؟
- چگونه رکورد مرتبط ایجاد کنیم؟
- چگونه دادههای رابطه را فیلتر کنیم؟
- Eager Loading و Lazy Loading چیست؟
withCount()وwhereHas()چه کاربردی دارند؟- چگونه از مشکل N+1 Query جلوگیری کنیم؟
- خطاهای رایج در رابطه یک به چند چیست؟
One to Many در Laravel چیست؟
One to Many به رابطهای گفته میشود که در آن یک رکورد از جدول اول میتواند با چند رکورد از جدول دوم ارتباط داشته باشد.
برای مثال تصور کنید یک فروشگاه اینترنتی داریم.
یک کاربر میتواند چند سفارش داشته باشد:
User
│
├── Order 1
├── Order 2
├── Order 3
└── Order 4
در این مثال:
Userرکورد والد یا Parent است.Orderرکورد فرزند یا Child است.- هر User میتواند چند Order داشته باشد.
- اما هر Order متعلق به یک User است.
بنابراین رابطه بین این دو جدول:
User 1 ─────────── N Order
است.
در Laravel برای تعریف این رابطه معمولاً از دو متد استفاده میکنیم:
hasMany()
در Model والد و:
belongsTo()
در Model فرزند.
# یک مثال واقعی از One to Many
فرض کنیم دو جدول داریم:
جدول users
users
--------------------------------
id
name
email
جدول orders
orders
--------------------------------
id
user_id
amount
status
created_at
ستون user_id مشخص میکند هر سفارش متعلق به کدام کاربر است.
مثلاً:
users
id name
1 Ali
2 Reza
3 Sara
و:
orders
id user_id amount
1 1 500000
2 1 800000
3 1 300000
4 2 900000
در این حالت:
Ali
├── Order 1
├── Order 2
└── Order 3
Reza
└── Order 4
Sara
└── بدون سفارش
این دقیقاً یک رابطه One to Many است.
# Foreign Key در رابطه One to Many
یکی از مهمترین مفاهیمی که هنگام کار با رابطه یک به چند باید بدانید، Foreign Key است.
در مثال User و Order، این رابطه با ستون زیر در جدول orders ایجاد میشود:
user_id
این ستون به id در جدول users اشاره میکند.
بنابراین:
users.id
↑
│
orders.user_id
نکته مهم این است که در رابطه One to Many، معمولاً Foreign Key در جدول سمت Many قرار میگیرد.
یعنی اگر:
User → Orders
داشته باشیم، user_id در جدول orders قرار میگیرد.
اگر:
Category → Products
داشته باشیم، category_id در جدول products قرار میگیرد.
اگر:
Post → Comments
داشته باشیم، post_id در جدول comments قرار میگیرد.
# ساخت Migration برای رابطه One to Many
فرض کنیم میخواهیم سیستم کاربران و سفارشها را ایجاد کنیم.
ابتدا Migration سفارشها را ایجاد میکنیم:
php artisan make:migration create_orders_table
سپس میتوانیم ساختار جدول را به شکل زیر تعریف کنیم:
Schema::create('orders', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')
->constrained('users')
->cascadeOnDelete();
$table->decimal('amount', 12, 2);
$table->string('status');
$table->timestamps();
});
در اینجا:
$table->foreignId('user_id')
ستون Foreign Key را ایجاد میکند.
و:
->constrained('users')
مشخص میکند که این کلید خارجی به جدول users مربوط است.
# cascadeOnDelete چیست؟
در مثال بالا از این عبارت استفاده کردیم:
->cascadeOnDelete()
یعنی اگر یک User حذف شود، رکوردهای مرتبط او در جدول orders نیز حذف شوند.
مثلاً:
User #1
├── Order #1
├── Order #2
└── Order #3
اگر User شماره ۱ حذف شود، با تنظیم Cascade، سفارشهای مرتبط نیز حذف میشوند.
البته استفاده از Cascade باید با منطق کسبوکار پروژه هماهنگ باشد.
برای مثال در یک سیستم مالی واقعی ممکن است نخواهید با حذف حساب کاربری، سابقه سفارش یا تراکنشهای مالی نیز حذف شود. در چنین شرایطی باید استراتژی دیگری برای نگهداری اطلاعات در نظر بگیرید.
# تعریف One to Many در Model
حالا باید رابطه را در Modelهای Laravel تعریف کنیم.
فرض کنیم دو Model داریم:
app/Models/User.php
app/Models/Order.php
در Model User رابطه را با hasMany() تعریف میکنیم.
رابطه در Model User
public function orders()
{
return $this->hasMany(Order::class);
}
یعنی:
> هر User میتواند چند Order داشته باشد.
پس ساختار Model میتواند به شکل زیر باشد:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function orders()
{
return $this->hasMany(Order::class);
}
}
# تعریف belongsTo در Model فرزند
حالا باید رابطه معکوس را در Order تعریف کنیم.
public function user()
{
return $this->belongsTo(User::class);
}
یعنی:
> هر Order متعلق به یک User است.
Model کامل:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
protected $fillable = [
'user_id',
'amount',
'status',
];
public function user()
{
return $this->belongsTo(User::class);
}
}
بنابراین رابطه ما به این شکل است:
User
└── hasMany()
↓
Orders
Order
└── belongsTo()
↓
User
# تفاوت hasMany و belongsTo
این دو متد را باید بهخوبی از یکدیگر تشخیص دهید.
| Model | متد | مفهوم |
|---|---|---|
| User | hasMany() | یک User چند Order دارد |
| Order | belongsTo() | یک Order متعلق به یک User است |
مثلاً:
$user->orders
لیست سفارشهای کاربر را برمیگرداند.
اما:
$order->user
کاربری که سفارش متعلق به اوست را برمیگرداند.
# دریافت تمام رکوردهای مرتبط
بعد از تعریف رابطه، دریافت سفارشهای یک کاربر بسیار ساده میشود.
$user = User::find(1);
$orders = $user->orders;
حالا $orders شامل سفارشهای کاربر شماره ۱ است.
میتوانیم آنها را نمایش دهیم:
foreach ($user->orders as $order) {
echo $order->amount;
}
# استفاده از Relationship بهصورت Query
رابطه فقط برای دریافت داده نیست.
میتوانیم روی رابطه Query نیز اجرا کنیم.
مثلاً:
$orders = $user->orders()
->where('status', 'paid')
->get();
در اینجا فقط سفارشهای پرداختشده کاربر دریافت میشوند.
یا:
$orders = $user->orders()
->latest()
->get();
برای دریافت سفارشها از جدیدترین به قدیمیترین.
# تفاوت orders و orders()
این موضوع برای بسیاری از افراد تازهکار گیجکننده است.
وقتی مینویسیم:
$user->orders
در واقع دادههای رابطه را دریافت میکنیم.
اما:
$user->orders()
خود Relationship را در اختیار ما قرار میدهد تا بتوانیم روی آن Query اجرا کنیم.
مثلاً:
$user->orders
برای دریافت داده مناسب است.
اما:
$user->orders()
->where('status', 'paid')
->get();
برای ساخت Query مناسب است.
# ایجاد رکورد Child از طریق Relationship
یکی از قابلیتهای مهم Eloquent این است که میتوانیم رکورد فرزند را مستقیماً از رابطه والد ایجاد کنیم.
مثلاً:
$user->orders()->create([
'amount' => 500000,
'status' => 'pending',
]);
Laravel بهصورت خودکار user_id مربوط به User را روی سفارش قرار میدهد.
یعنی به جای اینکه خودمان بنویسیم:
Order::create([
'user_id' => $user->id,
'amount' => 500000,
'status' => 'pending',
]);
میتوانیم از رابطه استفاده کنیم:
$user->orders()->create([
'amount' => 500000,
'status' => 'pending',
]);
این روش خوانایی بسیار خوبی دارد و ارتباط بین دادهها را نیز واضحتر نشان میدهد.
# استفاده از save برای ایجاد Child
روش دیگر استفاده از save() است:
$order = new Order();
$order->amount = 500000;
$order->status = 'pending';
$user->orders()->save($order);
در این حالت Laravel ارتباط سفارش با User را برقرار میکند.
# ایجاد چند رکورد با createMany
اگر بخواهیم چند سفارش ایجاد کنیم، میتوانیم از createMany() استفاده کنیم:
$user->orders()->createMany([
[
'amount' => 500000,
'status' => 'pending',
],
[
'amount' => 750000,
'status' => 'paid',
],
[
'amount' => 900000,
'status' => 'paid',
],
]);
این قابلیت زمانی کاربردی است که چند رکورد مرتبط را بهصورت همزمان ایجاد میکنیم.
# Mass Assignment و رابطه One to Many
اگر از create() یا createMany() استفاده میکنید، باید تنظیمات Mass Assignment Model را نیز در نظر بگیرید.
مثلاً:
protected $fillable = [
'amount',
'status',
];
در بسیاری از مواقع نیازی نیست user_id را در fillable قرار دهید، چون Relationship مقدار آن را هنگام ایجاد رکورد تنظیم میکند.
همیشه باید Mass Assignment را متناسب با ساختار واقعی پروژه تنظیم کنید و دادههای ورودی کاربر را بدون اعتبارسنجی و کنترل مستقیماً وارد Model نکنید.
# دریافت User از داخل Order
رابطه معکوس را نیز تعریف کردهایم:
public function user()
{
return $this->belongsTo(User::class);
}
بنابراین:
$order = Order::find(1);
$user = $order->user;
اکنون User مربوط به این سفارش در $user قرار دارد.
مثلاً:
echo $order->user->name;
میتواند نام کاربر صاحب سفارش را نمایش دهد.
# Eager Loading در One to Many
یکی از موضوعات مهم هنگام کار با Relationshipها، Eager Loading است.
فرض کنید میخواهیم کاربران را دریافت کنیم و برای هر کاربر سفارشهایش را نیز نمایش دهیم.
ممکن است بنویسیم:
$users = User::all();
foreach ($users as $user) {
foreach ($user->orders as $order) {
// ...
}
}
در پروژههای بزرگ، این روش میتواند باعث اجرای Queryهای متعدد شود.
برای چنین شرایطی میتوانیم از with() استفاده کنیم:
$users = User::with('orders')->get();
در این حالت Laravel رابطه orders را بهصورت Eager Loading بارگذاری میکند.
سپس:
foreach ($users as $user) {
foreach ($user->orders as $order) {
echo $order->amount;
}
}
# مشکل N+1 Query چیست؟
یکی از مشکلات رایج در استفاده نادرست از Relationshipها، N+1 Query است.
فرض کنید ۱۰۰ کاربر داریم و برای هر کاربر سفارشها را جداگانه دریافت کنیم.
ممکن است:
1 Query برای دریافت کاربران
+
100 Query برای دریافت سفارشهای کاربران
در نتیجه:
101 Query
اجرا شود.
اما با:
$users = User::with('orders')->get();
Laravel دادههای مرتبط را به شکل بهینهتری بارگذاری میکند.
به همین دلیل هنگام کار با Relationshipهای متعدد، شناخت Eager Loading اهمیت زیادی دارد.
# Lazy Loading در Laravel
وقتی رابطه را به این شکل استفاده میکنیم:
$user->orders
و قبلاً آن را Eager Load نکرده باشیم، Laravel میتواند در زمان دسترسی به Relationship آن را بارگذاری کند.
این رفتار را Lazy Loading مینامیم.
مثلاً:
$user = User::find(1);
$orders = $user->orders;
رابطه هنگام دسترسی به orders بارگذاری میشود.
Lazy Loading برای بعضی سناریوها بسیار راحت است، اما اگر در یک Loop روی تعداد زیادی Model استفاده شود، باید مراقب N+1 Query باشیم.
# شمارش رکوردهای مرتبط با withCount
گاهی فقط میخواهیم بدانیم هر User چند سفارش دارد و نیازی به دریافت تمام سفارشها نداریم.
در این حالت withCount() بسیار کاربردی است:
$users = User::withCount('orders')->get();
حالا:
$user->orders_count
تعداد سفارشهای کاربر را در اختیار ما قرار میدهد.
مثلاً:
foreach ($users as $user) {
echo $user->name . ': ';
echo $user->orders_count;
}
این روش برای صفحات مدیریتی، داشبوردها و گزارشها بسیار کاربردی است.
# فیلتر کردن Model بر اساس وجود Relationship
فرض کنید میخواهیم فقط کاربرانی را دریافت کنیم که حداقل یک سفارش دارند.
میتوانیم از has() استفاده کنیم:
$users = User::has('orders')->get();
برای مثال اگر بخواهیم کاربرانی را پیدا کنیم که حداقل سه سفارش دارند:
$users = User::has('orders', '>=', 3)->get();
این قابلیت برای فیلتر کردن دادهها بر اساس Relationship بسیار مفید است.
# استفاده از whereHas
گاهی میخواهیم والد را بر اساس شرایطی روی Childها فیلتر کنیم.
مثلاً فقط کاربرانی را میخواهیم که حداقل یک سفارش پرداختشده دارند:
$users = User::whereHas('orders', function ($query) {
$query->where('status', 'paid');
})->get();
یعنی:
> کاربرانی را پیدا کن که سفارشی با وضعیت paid دارند.
این قابلیت در پروژههای واقعی بسیار مهم است.
# Eager Loading همراه با شرط
میتوانیم Relationship را همراه با شرط نیز Load کنیم.
مثلاً:
$users = User::with([
'orders' => function ($query) {
$query->where('status', 'paid');
}
])->get();
در این حالت سفارشهای مرتبط فقط در صورتی بارگذاری میشوند که وضعیت آنها paid باشد.
# رابطه One to Many با Category و Product
رابطه User و Order تنها یک مثال است.
یکی از مثالهای بسیار رایج در فروشگاهها:
Category
│
├── Product
├── Product
├── Product
└── Product
یک Category میتواند چند Product داشته باشد.
در Model Category:
public function products()
{
return $this->hasMany(Product::class);
}
و در Model Product:
public function category()
{
return $this->belongsTo(Category::class);
}
در دیتابیس نیز:
products
------------------
id
category_id
name
price
خواهیم داشت.
# رابطه One to Many با Post و Comment
مثال بسیار رایج دیگر:
Post
│
├── Comment
├── Comment
└── Comment
یک مقاله میتواند چند دیدگاه داشته باشد.
در Post:
public function comments()
{
return $this->hasMany(Comment::class);
}
و در Comment:
public function post()
{
return $this->belongsTo(Post::class);
}
حالا میتوانیم بنویسیم:
$post->comments
یا:
$comment->post
# تغییر Foreign Key پیشفرض
Laravel بر اساس Convention معمولاً میتواند Foreign Key را بهصورت خودکار تشخیص دهد.
برای مثال:
$this->hasMany(Order::class);
در Model User معمولاً انتظار دارد Foreign Key در جدول orders برابر با:
user_id
باشد.
اما ممکن است در پروژهای از نام متفاوتی استفاده کرده باشید.
مثلاً:
customer_id
در این صورت میتوانیم Foreign Key را مشخص کنیم:
public function orders()
{
return $this->hasMany(Order::class, 'customer_id');
}
در سمت فرزند نیز میتوانیم کلید خارجی را مشخص کنیم:
public function user()
{
return $this->belongsTo(User::class, 'customer_id');
}
بنابراین همیشه لازم نیست از نامهای پیشفرض Laravel استفاده کنیم.
# تغییر Local Key
در حالت معمول Laravel رابطه را با id مدل والد برقرار میکند.
اما در شرایط خاص میتوانیم Local Key را نیز مشخص کنیم.
مثلاً:
return $this->hasMany(
Order::class,
'customer_code',
'code'
);
در این مثال:
orders.customer_code
↓
users.code
بهعنوان مبنای رابطه استفاده میشود.
البته استفاده از کلیدهای سفارشی باید با طراحی صحیح دیتابیس انجام شود و بهتر است تا حد امکان Conventionهای Laravel حفظ شوند.
# ویرایش رکوردهای مرتبط
Relationship به این معنی نیست که فقط میتوانیم رکورد ایجاد یا دریافت کنیم.
مثلاً:
$order = $user->orders()->find(10);
$order->update([
'status' => 'paid',
]);
در اینجا سفارش مربوط به User را پیدا کرده و وضعیت آن را تغییر میدهیم.
همچنین میتوانیم مستقیماً روی Query رابطه عملیات انجام دهیم:
$user->orders()
->where('status', 'pending')
->update([
'status' => 'cancelled',
]);
در این حالت سفارشهای Pending مربوط به همان User تغییر میکنند.
# حذف رکوردهای مرتبط
برای حذف یک سفارش:
$order->delete();
یا از طریق Relationship:
$user->orders()->where('id', 10)->delete();
اما باید بین دو مفهوم تفاوت قائل شویم:
حذف Child
و:
حذف Parent
اگر User را حذف کنیم، اینکه سفارشهای او نیز حذف شوند یا باقی بمانند، به طراحی Foreign Key و قوانین کسبوکار سیستم بستگی دارد.
# One to Many در یک پروژه واقعی Laravel
فرض کنیم در حال ساخت فروشگاه اینترنتی هستیم.
ساختار دیتابیس:
users
└── id
orders
├── id
├── user_id
├── amount
└── status
Model کاربر:
class User extends Authenticatable
{
public function orders()
{
return $this->hasMany(Order::class);
}
}
Model سفارش:
class Order extends Model
{
protected $fillable = [
'amount',
'status',
];
public function user()
{
return $this->belongsTo(User::class);
}
}
حالا ایجاد سفارش:
$user->orders()->create([
'amount' => 1200000,
'status' => 'pending',
]);
دریافت سفارشها:
$orders = $user->orders;
دریافت کاربر سفارش:
$user = $order->user;
دریافت کاربران دارای سفارش:
$users = User::has('orders')->get();
دریافت تعداد سفارشها:
$users = User::withCount('orders')->get();
و دریافت کاربرانی که سفارش پرداختشده دارند:
$users = User::whereHas('orders', function ($query) {
$query->where('status', 'paid');
})->get();
این مجموعه تقریباً بخش زیادی از نیازهای رایج One to Many را پوشش میدهد.
# اشتباهات رایج در One to Many
۱. قرار دادن Foreign Key در جدول اشتباه
در رابطه:
User → Orders
معمولاً باید:
orders.user_id
وجود داشته باشد، نه اینکه چند شناسه سفارش را داخل جدول User ذخیره کنیم.
۲. ذخیره چند ID در یک ستون
برای مثال این ساختار مناسب نیست:
users
id | order_ids
1 | 1,2,3,4
این روش برخلاف طراحی رابطهای صحیح دیتابیس است.
بهتر است هر Order یک رکورد مستقل داشته باشد:
orders
id | user_id
1 | 1
2 | 1
3 | 1
4 | 1
۳. اشتباه گرفتن hasMany و belongsTo
این کد:
$user->orders()
از hasMany() استفاده میکند.
ولی:
$order->user()
از belongsTo() استفاده میکند.
اگر این دو رابطه را اشتباه تعریف کنید، Eloquent نمیتواند Relationship را به شکل مورد انتظار شما مدیریت کند.
۴. فراموش کردن Foreign Key
اگر جدول orders ستون:
user_id
نداشته باشد، رابطه استاندارد User و Order به شکل مورد انتظار کار نخواهد کرد.
۵. ایجاد N+1 Query
این الگو را باید با دقت استفاده کنید:
$users = User::all();
foreach ($users as $user) {
echo $user->orders->count();
}
اگر دادهها زیاد باشند، بهتر است از:
User::withCount('orders')->get();
یا در صورت نیاز:
User::with('orders')->get();
استفاده کنید.
# چه زمانی از One to Many استفاده کنیم؟
هر زمان یک رکورد میتواند چند رکورد مرتبط داشته باشد، One to Many یکی از گزینههای اصلی شماست.
نمونههای رایج:
| Parent | Child |
|---|---|
| User | Order |
| User | Address |
| Category | Product |
| Post | Comment |
| Country | City |
| Company | Employee |
| Course | Lesson |
| Brand | Product |
| Invoice | Invoice Item |
| Ticket | Ticket Message |
البته انتخاب نوع Relationship باید بر اساس منطق واقعی دادهها انجام شود.
# تفاوت One to One و One to Many
در مقاله قبلی با One to One آشنا شدیم.
تفاوت اصلی این دو رابطه تعداد رکوردهای مرتبط است.
One to One
User
│
└── Profile
یک User یک Profile دارد.
One to Many
User
├── Order
├── Order
└── Order
یک User چند Order دارد.
در Laravel نیز معمولاً:
hasOne()
برای One to One و:
hasMany()
برای One to Many استفاده میشود.
# تفاوت One to Many و Many to Many
در One to Many:
Category
↓
Products
هر Product معمولاً به یک Category تعلق دارد.
اما در Many to Many ممکن است:
Product
↔
Category
باشد؛ یعنی یک Product بتواند چند Category داشته باشد و یک Category نیز چند Product داشته باشد.
در چنین شرایطی معمولاً به یک جدول واسط یا Pivot Table نیاز داریم.
این موضوع در مقاله بعدی یعنی Many to Many در Laravel بررسی خواهد شد.
# نکات مهم برای استفاده حرفهای از One to Many
برای اینکه Relationshipهای پروژه Laravel شما در پروژههای واقعی قابل نگهداری باشند، چند نکته را همیشه در نظر داشته باشید:
۱. از Conventionهای Laravel استفاده کنید
نامهایی مانند:
user_id
category_id
post_id
باعث میشوند Eloquent بتواند Relationshipها را راحتتر تشخیص دهد.
۲. Foreign Key را بهدرستی تعریف کنید
ترجیحاً Constraintهای دیتابیس را جدی بگیرید.
۳. برای دادههای زیاد از Eager Loading استفاده کنید
مثلاً:
User::with('orders')->get();
۴. برای شمارش فقط از withCount استفاده کنید
اگر فقط تعداد را لازم دارید:
User::withCount('orders')->get();
بهتر است کل سفارشها را بیدلیل Load نکنید.
۵. N+1 Query را جدی بگیرید
در پروژههای کوچک ممکن است متوجه آن نشوید، اما در پروژههای بزرگ میتواند روی عملکرد برنامه تأثیر قابل توجهی داشته باشد.
۶. حذف Cascade را با منطق کسبوکار هماهنگ کنید
برای اطلاعات حساس مانند تراکنشهای مالی، حذف خودکار دادهها همیشه انتخاب مناسبی نیست.
# جمعبندی
One to Many در Laravel یکی از پرکاربردترین Relationshipهای Eloquent است و زمانی استفاده میشود که یک رکورد از جدول والد بتواند چند رکورد در جدول فرزند داشته باشد.
ساختار اصلی آن به این شکل است:
Parent
│
└── hasMany()
↓
Child
و در جهت معکوس:
Child
│
└── belongsTo()
↓
Parent
برای مثال در سیستم سفارش:
User
├── Order
├── Order
└── Order
در Model کاربر:
public function orders()
{
return $this->hasMany(Order::class);
}
و در Model سفارش:
public function user()
{
return $this->belongsTo(User::class);
}
بعد از تعریف Relationship میتوانیم بهسادگی دادههای مرتبط را دریافت کنیم:
$user->orders;
سفارش ایجاد کنیم:
$user->orders()->create([
'amount' => 500000,
'status' => 'pending',
]);
تعداد سفارشها را بگیریم:
User::withCount('orders')->get();
و بر اساس Relationship فیلتر کنیم:
User::whereHas('orders', function ($query) {
$query->where('status', 'paid');
})->get();
بنابراین یادگیری hasMany() و belongsTo() یک مرحله مهم در مسیر یادگیری Eloquent و توسعه پروژههای واقعی Laravel است.
# سوالات متداول
One to Many در Laravel چیست؟
One to Many رابطهای است که در آن یک رکورد والد میتواند چند رکورد فرزند داشته باشد؛ مانند یک User که چند Order دارد.
برای One to Many در Laravel از چه متدی استفاده میشود؟
در Model والد معمولاً از:
hasMany()
و در Model فرزند از:
belongsTo()
استفاده میشود.
Foreign Key در One to Many کجا قرار میگیرد؟
معمولاً Foreign Key در جدول سمت Many قرار میگیرد. مثلاً در رابطه User و Order، ستون user_id در جدول orders قرار دارد.
چگونه سفارشهای یک User را دریافت کنیم؟
بعد از تعریف رابطه:
$user->orders;
چگونه یک Order برای User ایجاد کنیم؟
میتوانیم از Relationship استفاده کنیم:
$user->orders()->create([
'amount' => 500000,
'status' => 'pending',
]);
تفاوت hasMany و belongsTo چیست؟
hasMany() رابطه والد با چند فرزند را تعریف میکند و belongsTo() رابطه فرزند با والد را مشخص میکند.
چگونه تعداد رکوردهای مرتبط را دریافت کنیم؟
با withCount():
$users = User::withCount('orders')->get();
سپس:
$user->orders_count
در دسترس خواهد بود.
چگونه از N+1 Query جلوگیری کنیم؟
در صورت نیاز از Eager Loading استفاده کنید:
User::with('orders')->get();
یا اگر فقط تعداد رکوردها لازم است:
User::withCount('orders')->get();





