Laravel Eloquent Relationship Basics

লারাভেলে, Eloquent relationship হল object-oriented techniques ব্যবহার করে দুটি ডাটাবেস টেবিলের মধ্যে সংযোগ করাকে বুঝায়। এটি আপনাকে বিভিন্ন ধরণের ডাটাবেস অপারেশন করতে দেয়, যেমন একাধিক টেবিল এর related data ডেটা গুলোকে retrieving করা, একসাথে একাধিক টেবিল এ relationships যুক্ত নতুন রেকর্ড তৈরি করা, একাধিক টেবিল এ relationships যুক্ত এক বা একাধিক ডেটা আপডেট করা এবং এক বা একাধিক টেবিল এর related রেকর্ডগুলি মুছে ফেলা।

Eloquent হল Laravel-এর বিল্ট-ইন ORM (Object-Relational Mapping) সিস্টেম, যা আপনার ডাটাবেসের সাথে ইন্টারঅ্যাক্ট করার একটি সহজ এবং অভিব্যক্তিপূর্ণ উপায় প্রদান করে। Eloquent relationships গুলির সাহায্যে, আপনি নির্ধারণ করতে পারেন কিভাবে বিভিন্ন ডাটাবেস টেবিল একে অপরের সাথে রিলেটেড, যেমন one-to-one, one-to-many, many-to-one, এবং many-to-many relationships.

একটি Eloquent relationship সংজ্ঞায়িত করার জন্য, আপনি সাধারণত আপনার ইলোকুয়েন্ট মডেল ক্লাসের মধ্যে methods গুলি সংজ্ঞায়িত করেন। এই methods গুলি relationship এর ধরন নির্দিষ্ট করে এবং relationship টেবিলের বিবরণ প্রদান করে, যেমন relationship এর জন্য ব্যবহৃত foreign key এবং primary key কলাম।

Laravel Common Eloquent Relationships

নিম্নে কিছু common types এর Eloquent relationships এর পরিচিতি দেওয়া হয়েছে:

  • One-to-One Relationship: One-to-One Relationship এ, প্রথম টেবিলের প্রতিটি রেকর্ড দ্বিতীয় টেবিলের একটি রেকর্ডের সাথে যুক্ত থাকে এবং একইভাবে দ্বিতীয় টেবিলের প্রতিটি রেকর্ড প্রথম টেবিলের একটি রেকর্ডের সাথে যুক্ত থাকে। উদাহরণস্বরূপ, প্রতিটি ইউজারের একটি করে প্রোফাইল আছে এবং একইভাবে আমরা বলতে পারি প্রতিটি প্রোফাইলের বিপরীতে একটি করে ইউজার আছে।
  • One-to-Many Relationship: One-to-Many Relationship এ, প্রথম টেবিলের প্রতিটি রেকর্ড দ্বিতীয় টেবিলের একাধিক রেকর্ডের সাথে যুক্ত হতে পারে, কিন্তু দ্বিতীয় টেবিলের প্রতিটি রেকর্ড প্রথম টেবিলের শুধুমাত্র একটি রেকর্ডের সাথে যুক্ত। . উদাহরণস্বরূপ, একজন ব্যবহারকারীর অনেক পোস্ট আছে।
  • Many-to-One Relationship: many-to-one relationship এ, প্রথম টেবিলের একাধিক রেকর্ড দ্বিতীয় টেবিলের একক রেকর্ডের সাথে যুক্ত হতে পারে। উদাহরণস্বরূপ, একাধিক পোস্ট একক ব্যবহারকারীর অন্তর্গত।
  • Many-to-Many Relationship: Many-to-Many Relationship এ, প্রথম টেবিলের একাধিক রেকর্ড দ্বিতীয় টেবিলের একাধিক রেকর্ডের সাথে যুক্ত হতে পারে। উদাহরণস্বরূপ, ইউজারদের একাধিক roles থাকতে পারে এবং একাধিক roles ইউজারদের উপর বরাদ্দ করা যেতে পারে।

তবে উপরোক্ত Eloquent Relationship গুলো ছাড়াও Laravel আরো কিছু Eloquent Relationship সুবিধা প্রদান করে। আর সেগুলো নিম্নরূপ:

  • Has One Of Many: এটা অনেকটা এমন যেখানে একটি মডেলের অন্য মডেলের অনেক রেকর্ডের সাথে Relationship রয়েছে , যার থেকে আপনার শুধু একটি related রেকর্ড দরকার। ধরা যাক আপনার User এবং Phone নামে দুটি Model রয়েছে। প্রতিটি ইউজারের একাধিক ফোন থাকতে পারে, কিন্তু আপনি “primary” ফোন হিসাবে শুধুমাত্র একটি ফোন retrieve করতে চান৷
  • Has One Through:লারাভেলের Eloquent relationship system এ , “Has One Through” relationship হচ্ছে আপনাকে এমন একটি relationship কে সংজ্ঞায়িত করতে দেয় যা অন্য মধ্যবর্তী মডেলের মধ্য দিয়ে যাওয়া জড়িত। আপনি যখন তৃতীয় মডেলের মাধ্যমে পরোক্ষভাবে একটি related model এ অ্যাক্সেস করতে চান তখন এই relationship টি কার্যকর। ধরুন আপনার তিনটি মডেল রয়েছে: User, Country এবং Profile. প্রতিটি User Model একটি Country Model এর অন্তর্গত, এবং প্রতিটি Profile Model একটি User Model এর অন্তর্গত। যাইহোক, আপনি User মডেলে এমন একটি relationship কে সংজ্ঞায়িত করতে চান যাতে User মডেল Profile মডেল এর মাধ্যমে সরাসরি যুক্ত Country Model এ অ্যাক্সেস করতে পারে।
  • Has Many Through: লারাভেলের Eloquent relationship system এ, “Has Many Through” এমন একটি relationship কে সংজ্ঞায়িত করতে দেয় যা একটি related model অ্যাক্সেস করার জন্য একটি মধ্যবর্তী মডেলের মধ্য দিয়ে অতিক্রম করে। আপনি যখন অন্য মডেলের মাধ্যমে পরোক্ষভাবে একটি মডেল থেকে একাধিক related records পুনরুদ্ধার করতে চান তখন এই relationship টি কার্যকর। ধরুন আপনার Country, User, এবং Post নামের তিনটি মডেল রয়েছে। প্রতিটি Country তে একাধিক ইউজার রয়েছে এবং প্রতিটি ইউজারের একাধিক পোস্ট রয়েছে। যাইহোক, আপনি সেই দেশের ইউজারদের সাথে যুক্ত সমস্ত পোস্ট সরাসরি অ্যাক্সেস করার জন্য country মডেলের একটি relationship কে সংজ্ঞায়িত করতে চান।

Mastering Laravel with ReactJS Course

Laravel Polymorphic Relationship

লারাভেলের Eloquent relationship system এ, একটি polymorphic (বহুরূপীয়) relationship একটি মডেলকে একটি একক অ্যাসোসিয়েশনের একাধিক অন্যান্য মডেলের সাথে related হতে দেয়। এটি একটি মডেলকে অন্যান্য মডেলের সাথে যুক্ত করার একটি ফ্লেক্সিবল উপায় প্রদান করে, তাদের নির্দিষ্ট প্রকার নির্বিশেষে।

Polymorphic relationships গুলি তখনি উপযোগী হয় যখন আপনার এমন পরিস্থিতি থাকে যেখানে একটি মডেল একাধিক অন্যান্য মডেলের অন্তর্গত হতে পারে এবং আপনি প্রতিটি relationship মডেলের জন্য পৃথক foreign key columns তৈরি না করে একটি relationship স্থাপন করতে চান।

ধারণাটি ব্যাখ্যা করতে, একটি উদাহরণ বিবেচনা করুন যেখানে আপনার কাছে একটি Comment model রয়েছে যা Post এবং Video এর মতো অন্যান্য মডেলের সাথে যুক্ত হতে পারে। প্রতিটি related মডেলের জন্য পৃথক foreign key কলাম তৈরি করার পরিবর্তে, আপনি একটি polymorphic (বহুরূপী) relationship এ ব্যবহার করতে পারেন।

এই ধরেনের Polymorphic Relationship গুলো লারাভেলে তিন ভাবে সমাধান করা হয় :

  • Polymorphic One-to-One Relationship
  • Polymorphic One-to-Many Relationship
  • Polymorphic Many-to-Many Relationship

এবার চলুন নিচের প্রতিটি Relationship নিয়ে আলোচনা করা যাক :

One-to-One Relationship

যেমনটি ইতিপূর্বে বলেছি, One-to-One Relationship এ, প্রথম টেবিলের প্রতিটি রেকর্ড দ্বিতীয় টেবিলের একটি রেকর্ডের সাথে যুক্ত থাকে এবং একইভাবে দ্বিতীয় টেবিলের প্রতিটি রেকর্ড প্রথম টেবিলের একটি রেকর্ডের সাথে যুক্ত থাকে। উদাহরণস্বরূপ, প্রতিটি ইউজারের একটি করে প্রোফাইল আছে এবং একইভাবে আমরা বলতে পারি প্রতিটি প্রোফাইলের বিপরীতে একটি করে ইউজার আছে।

এবার চলুন আমাদের User Table এবং Profile Table কেমন হতে পারে তা দেখা যাক :

User and Profile Table Structure for One-to-One Relationship
User and Profile Table Structure for One-to-One Relationship

উপরোক্ত Table Structure এ, “User” টেবিলটি unique IDs, usernames এবং emails সহ user accounts গুলিকে রিপ্রেজেন্ট করে৷ “Profile” টেবিলে প্রতিটি ইউজার সম্পর্কে অতিরিক্ত তথ্য রয়েছে, যেমন তাদের first name, last name, age এবং gender. আবার “Profile” টেবিলের “User_ID” কলামটি একটি foreign key হিসাবে কাজ করে, “User” টেবিলে সংশ্লিষ্ট ইউজারকে উল্লেখ করে।

এই one-to-one relationship নিশ্চিত করে যে প্রতিটি ইউজারের একটি করে প্রোফাইল আছে এবং একইভাবে আমরা বলতে পারি প্রতিটি প্রোফাইলের বিপরীতে একটি করে ইউজার আছে।

এবার নিম্নোক্ত কমান্ডের users Table এবং Profiles Table এর জন্য দুটি Migration File তৈরি করি:

php artisan make:migration users
php artisan make:migration profiles

এবার সদ্য তৈরি হওয়া database/migrations/users এবং database/migrations/profiles ফাইল দুটিকে নিচের মতো করে আপডেট করে নিন:

(e.g., “20230524120000_create_users_table.php”) :

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('username');
            $table->string('email');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('users');
    }
};


(e.g., “20230524120100_create_profiles_table.php”):

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('profiles', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('user_id');
            $table->string('first_name');
            $table->string('last_name');
            $table->integer('age');
            $table->string('gender');
            $table->timestamps();

            $table->foreign('user_id')->references('id')->on('users');
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('profiles');
    }
};

এবার নিম্নোক্ত কমান্ডের মাধ্যমে টেবিল দুটি তৈরি করে ফেলুনঃ

php artisan migrate

এবার users table এবং profile table এ কিছু dummy ডেটা ঢুকানোর জন্য নিম্নোক্ত কমান্ডের মাধ্যমে দুটি seeder file তৈরি করে ফেলুন :

php artisan make:seeder UsersTableSeeder
php artisan make:seeder ProfilsTableSeeder

এবার সদ্য তৈরি হওয়া database/seeders/UsersTableSeeder এবং database/seeders/ProfilesTableSeeder ফাইল দুটিকে নিচের মতো করে আপডেট করে নিন:

UsersTableSeeder.php

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class UsersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        DB::table('users')->insert([
            [
                'username' => 'johnsmith',
                'email' => 'john@example.com',
            ],
            [
                'username' => 'sarahjane',
                'email' => 'sarah@example.com',
            ],
            [
                'username' => 'mikethomas',
                'email' => 'mike@example.com',
            ],
        ]);
    }
}

ProfilesTableSeeder.php

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class ProfilesTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        DB::table('profiles')->insert([
            [
                'user_id' => 1,
                'first_name' => 'John',
                'last_name' => 'Smith',
                'age' => 30,
                'gender' => 'Male',
            ],
            [
                'user_id' => 2,
                'first_name' => 'Sarah',
                'last_name' => 'Jane',
                'age' => 35,
                'gender' => 'Female',
            ],
            [
                'user_id' => 3,
                'first_name' => 'Mike',
                'last_name' => 'Thomas',
                'age' => 28,
                'gender' => 'Male',
            ],
        ]);
    }
}

এবার DatabaseSeeder.php ফাইলে গিয়ে Seeder File দুটি নিম্নোক্ত উপায়ে রেজিস্ট্রি করে দিন।

<?php

namespace Database\Seeders;

// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     */
    public function run(): void
    {
        $this->call([
            UsersTableSeeder::class,
            ProfilesTableSeeder::class,

        ]);
    }
}

সর্বশেষ নিম্নোক্ত কমান্ডের মাধ্যমে dummy ডেটা গুলো users table এবং profile table এ insert করুন :

php artisan db:seed

এতক্ষনে আপনার ডেটাবেসে users table এবং profiles table এ One-to-One relationship করার জন্য প্রয়োজনীয় ডেটা ইনসার্ট হয়ে গেছে। এখন আমরা User এবং Profile নামে দুটি মডেল তৈরি করব। এবং One-to-One রিলেশনশিপ এর জন্য প্রয়োজনীয় কোড লিখব।

User এবং Profile নামে দুটি মডেল তৈরির জন্য নিম্নোক্ত আর্টিসান কমান্ড রান করুন:

php artisan make:model User
php artisan make:model Profile

এবার সদ্য তৈরি হওয়া User Model এবং Profile Model কে নিচের মতো করে আপডেট করে নিন :

User Model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;

class User extends Model
{
    use HasFactory;

    protected $fillable = ['name', 'email'];

    public function profile(): HasOne
    {
        return $this->hasOne(Profile::class);
    }
}

Profile Model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Profile extends Model
{
    use HasFactory;

    protected $fillable = ['user_id', 'first_name', 'last_name', 'age', 'gender'];

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
}

এবার আপনি নিম্নোক্ত Route লেখার মাধ্যমে Laravel One-to-One Relationship পরীক্ষা করতে পারেন:

use App\Models\User;

Route::get('/getage/{user_id}',function($user_id){
    $user = User::find($user_id); 

    if ($user) {
        $age = $user->profile->age;
        echo $age;
    } else {
        echo "User not found";
    }
});

Mastering Laravel with ReactJS Course

Insert with One-to-One Relationship Tables

এখন যদি আপনি One-to-One Relationship যুক্ত দুটি table কোনো ডেটা insert করতে চান , তাহলে আপনি নিম্নোক্ত পদ্ধতি ব্যবহার করতে পারেন :

use App\Models\User;
use App\Models\Profile;

Route::get('/insert',function(){

    // Create a new user
    $user = new User();
    $user->username = 'mamnun';
    $user->email = 'mamnun@example.com';
    $user->save();

    // Create a new profile
    $profile = new Profile();
    $profile->user_id = $user->id;
    $profile->first_name = 'Mamnun';
    $profile->last_name = 'Bin Masud';
    $profile->age = 9;
    $profile->gender = 'Male';
    $profile->save();

});

Update with One-to-One Relationship Tables

এখন যদি আপনি One-to-One Relationship যুক্ত দুটি table কোনো ডেটা update করতে চান , তাহলে আপনি নিম্নোক্ত পদ্ধতি ব্যবহার করতে পারেন :

use App\Models\User;
use App\Models\Profile;
Route::get('/update',function(){

    // Create a new user
   $user = User::find(4);
    $user->username = 'mamnun';
    $user->email = 'mamnun@gmail.com';
    $user->save();

    // Create a new profile
    $profile = $user->profile;
    $profile->age = 10;
    $profile->save();

});

Delete with One-to-One Relationship Tables

আপনি যদি One-to-One Relationship যুক্ত দুটি table কোনো ডেটা delete করতে চান , তাহলে আপনি নিম্নোক্ত পদ্ধতি ব্যবহার করতে পারেন :

use App\Models\User;
use App\Models\Profile;
Route::get('/delete',function(){

    // Create a new user
   $user = User::find(4);
   if ($user) {
    // Retrieve the associated profile
    $profile = $user->profile;

    if ($profile) {
        // Delete the profile
        $profile->delete();
    }

    // Delete the user
    $user->delete();
}

});

One-to-many Relationship

যেমনটা ইতিমধ্যেই বলেছি One-to-Many Relationship এ, প্রথম টেবিলের প্রতিটি রেকর্ড দ্বিতীয় টেবিলের একাধিক রেকর্ডের সাথে যুক্ত হতে পারে, কিন্তু দ্বিতীয় টেবিলের প্রতিটি রেকর্ড প্রথম টেবিলের শুধুমাত্র একটি রেকর্ডের সাথে যুক্ত। . উদাহরণস্বরূপ, একজন ইউজারের অনেক পোস্ট আছে।

users Table এর স্ট্রাকচার ইতিমধ্যে উপরে দেওয়া হয়েছে, এবার posts Table টি কেমন হতে পারে তা দেখা যাক :

Laravel Posts Table Structure for One to many Relationship
Laravel Posts Table Structure for One to many Relationship

“posts” টেবিলটি একটি foreign key হিসাবে user_id কলাম ব্যবহার করে “users” টেবিলের সাথে যুক্ত। প্রতিটি পোস্টের একটি unique ID থাকে, user_id উল্লেখ করে যে কোন ইউজার পোস্ট করেছেন, পোস্টের টাইটেল, পোস্টের কনটেন্ট এবং created_at এবং updated_at-এর জন্য timestamps

“posts” টেবিলের sample data গুলো one-to-many relationship প্রদর্শন করে, যেখানে John Doe (user ID 1) তিনটি পোস্ট করেছেন এবং Jane Smith (user ID 2) শুধুমাত্র একটি পোস্ট করেছেন৷

তো চলুন উপরোক্ত স্ট্রাকচার অনুযায়ী একটি Migration File এবং একটি seeder File তৈরি করে ফেলি৷

posts table এর জন্য Migration File তৈরির জন্য নিম্নোক্ত আর্টিসান কমান্ডটি প্রয়োগ করুন :

php artisan make:migration posts

এবার সদ্য তৈরি হওয়া Migration File টি কে নিচের মতো করে আপডেট করুন :

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('user_id');
            $table->string('title');
            $table->text('content');
            $table->timestamps();

            // Define foreign key constraint
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('posts');
    }
};

এবার আবার নিম্নোক্ত কমান্ডের মাধ্যমে Migration File টি রান করার মাধ্যমে আপনার posts নামক টেবিল স্ট্রাকচার তৈরি করে ফেলুন :

php artisan migrate --path=/database/migrations/your_migration_file.php

এতক্ষনে আপনার posts নামক টেবিলের স্ট্রাকচার তৈরি হয়েগেছে। এখন আমরা কিছু dummy ডেটা ইনসার্টের জন্য একটা seeder file তৈরি করব। posts table এর জন্য একটা seeder file তৈরির জন্য নিম্নোক্ত কমান্ডটি লিখুন :

php artisan make:seeder PostsTableSeeder

এবার সদ্য তৈরি হওয়া database/seeders/PostsTableSeeder File এ নিচের মতো করে আপডেট করে নিন:

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;

class PostsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
          // Clear existing records in the posts table
          DB::table('posts')->truncate();

          // Create sample posts
          DB::table('posts')->insert([
              [
                  'user_id' => 1,
                  'title' => 'First Post by John Doe',
                  'content' => 'This is the content of the first post',
              ],
              [
                  'user_id' => 1,
                  'title' => 'Second Post by John Doe',
                  'content' => 'This is the content of the second post',
              ],
              [
                  'user_id' => 2,
                  'title' => 'Post by Jane Smith',
                  'content' => 'This is the content of Jane\'s post',
              ],
              [
                  'user_id' => 1,
                  'title' => 'Third Post by John Doe',
                  'content' => 'This is the content of the third post',
              ],
          ]);
  
          // Additional posts can be inserted as needed
    }
}

এবার DatabaseSeeder.php ফাইলে গিয়ে PostsTableSeeder File টি নিম্নোক্ত উপায়ে রেজিস্ট্রি করে দিন।

<?php

namespace Database\Seeders;

// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     */
    public function run(): void
    {
        $this->call([
            UsersTableSeeder::class,
            ProfilesTableSeeder::class,
            PostsTableSeeder::class,


        ]);
    }
}

যেহেতু ইতিপূর্বে আপনার users table এর জন্য seeding করা আছে , তাই এখন শুধুমাত্র posts টেবিল এর জন্য নিম্নোক্ত কমান্ডের মাধ্যমে seed টি রান করুন :

php artisan db:seed --class=PostsTableSeeder

মোটামুটি আমাদের ডাটাবেসের প্রস্তুতি শেষ। এখন আমরা one-to-many relationship বুঝার জন্য প্রথমে posts টেবিলটির নিম্নোক্ত আর্টিসান কমান্ডের মাধ্যমে Post Model টি তৈরি করব :

php artisan make:model Post

এবার User Model এবং Post মডেলকে নিচের মতো করে আপডেট করে নিন :

User Model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasMany;

class User extends Model
{
    use HasFactory;

    protected $fillable = ['name', 'email'];

    public function profile(): HasOne
    {
        return $this->hasOne(Profile::class);
    }

     /**
     * Get the posts for the user.
     */
    public function posts(): HasMany
    {
        return $this->hasMany(Post::class);
    }
}

Post Model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Post extends Model
{
    use HasFactory;

    /**
     * Get the user that owns the post.
     */
    public function user():BelongsTo
    {
        return $this->belongsTo(User::class);
    }
}

এবার আপনি নিম্নোক্ত route এর মাধ্যমে User Model এবং Post Model এর মধ্যে One-To-Many relationship চেক করতে পারেন :

use App\Models\User;
use App\Models\Post;
Route::get('/getposts/{user_id}',function($user_id){
    $user = User::find($user_id); 
    $allPosts=$user->posts;
    if ($allPosts->isEmpty()) {
        echo "No Post found";
    } else {
        
        foreach($allPosts as $post){
            echo $post->id,"=>",$post->title,"<br>";
        }
    }
});

একইভাবে আপনি নিম্নোক্ত route এর মাধ্যমে User Model এবং Post Model এর মধ্যে Many-To-One relationship চেক করতে পারেন :

use App\Models\Post;
use App\Models\User;

Route::get('/getuser/{post_id}',function($post_id){
    $postId = $post_id;
    $post = Post::find($postId);
    
    if ($post) {
        $user = $post->user;
        
        if ($user) {
            echo $user->username;
            // User found
            // Access the user information using $user variable
        } else {
            echo "User Not Found";
            // User not found for the given post ID
            // Handle the case when the user is not available
        }
    } else {
            echo "No Post Found";
        // Post not found for the given post ID
        // Handle the case when the post is not available
    }  
});

Mastering Laravel with ReactJS Course

Insert with One-to-Many Relationship Tables

এখন যদি আপনি One-to-Many Relationship যুক্ত দুটি table সম্পূর্ণ নতুন ইউজার সহ কোনো ডেটা insert করতে চান , তাহলে আপনি নিম্নোক্ত পদ্ধতি ব্যবহার করতে পারেন :

Route::get('/insert2',function(){

    // Create a new user
    $user = new User();
    $user->username = 'muhib';
    $user->email = 'muhib@example.com';
    $user->save();

    // Create new posts
    $posts = [
        ['title' => 'Post 1', 'content' => 'This is post 1 content.'],
        ['title' => 'Post 2', 'content' => 'This is post 2 content.'],
        ['title' => 'Post 3', 'content' => 'This is post 3 content.'],
    ];

    foreach ($posts as $postData) {
        $post = new Post();
        $post->title = $postData['title'];
        $post->content = $postData['content'];

        // Associate the post with the user
        $post->user_id = $user->id;

        $post->save();
    }
});

আবার যদি আপনি One-to-Many Relationship যুক্ত দুটি table সম্পূর্ণ বিদ্যমান ইউজার এর অধীনে কোনো ডেটা insert করতে চান , তাহলে আপনি নিম্নোক্ত পদ্ধতি ব্যবহার করতে পারেন :

Route::get('/insert2',function(){

    // Retrieve the existing user
    $user = User::find(2);

    if ($user) {
        // Create an array of post data
        $postsData = [
            ['title' => 'Post 1', 'content' => 'This is post 1 content.'],
            ['title' => 'Post 2', 'content' => 'This is post 2 content.'],
            ['title' => 'Post 3', 'content' => 'This is post 3 content.'],
        ];

        // Create an array to store the created posts
        $createdPosts = [];

        foreach ($postsData as $postData) {
            $post = new Post();
            $post->title = $postData['title'];
            $post->content = $postData['content'];

            // Associate the post with the existing user
            $post->user()->associate($user);

            $post->save();

            $createdPosts[] = $post;
        }

        // $createdPosts now contains the created posts associated with the user
    }

});

Update with One-to-Many Relationship Tables

আপনি যদি One-to-Many Relationship যুক্ত দুটি table সম্পূর্ণ বিদ্যমান ইউজার এর অধীনে কোনো ডেটা update করতে চান , তাহলে আপনি নিম্নোক্ত পদ্ধতি ব্যবহার করতে পারেন :

Route::get('/update2',function(){

    // Retrieve the existing user
    $user = User::find(2);

    if ($user) {
        // Retrieve the specific post to update
        $post = $user->posts()->find(8);

        if ($post) {
            // Update the attributes of the post
            $post->title = 'Updated Title';
            $post->content = 'Updated Content';

            // Save the updated post
            $post->save();
        }
    }

});

Delete with One-to-Many Relationship Tables

দরুন আপনি One-to-Many relationship এর বেলায় একজন ইউজারের সবগুলো post মুছে দিতে চান। সেক্ষেত্রে আপনি নিম্নোক্ত কৌশল প্রয়োগ করতে পারেন :

Route::get('/delete2',function(){

  // Retrieve the user
    $user = User::find(2);

    if ($user) {
        // Retrieve the associated posts
        $posts = $user->posts;

        // Delete the posts
        foreach ($posts as $post) {
            $post->delete();
        }

        // Optionally, delete the user
        // $user->delete();
    }

});

many-to-many Relationship

যেমনটা ইতিমধ্যেই বলেছি Many-to-Many Relationship এ, প্রথম টেবিলের একাধিক রেকর্ড দ্বিতীয় টেবিলের একাধিক রেকর্ডের সাথে যুক্ত হতে পারে। উদাহরণস্বরূপ, ইউজারদের একাধিক roles থাকতে পারে এবং একাধিক roles ইউজারদের উপর বরাদ্দ করা যেতে পারে।

আর এই many-to-many Relationship এর কাজ বুঝার জন্য আমরা roles এবং role_user নামক দুটি table তৈরি করব। টেবিল দুটির স্ট্রাকচার নিম্নরুপঃ

Laravel Role Table Structure
Laravel Role Table Structure
role_user table structure
role_user table structure

এই table দুটিতে, roles টেবিলটি আপনার সিস্টেমের বিভিন্ন roles রিপ্রেজেন্ট করে, এবং roles এবং users টেবিল এর মধ্যে many-to-many relationship স্থাপন করতে role_user টেবিলটি pivot table হিসাবে কাজ করে।

role_user table এ foreign keys হিসেবে role_id এবং user_id রয়েছে, যা যথাক্রমে roles এবং users টেবিলের আইডি কলামগুলি উল্লেখ করে। এই foreign keys গুলি roles এবং users টেবিলের মধ্যে সংযোগ স্থাপন করে।

তো চলুন উপরোক্ত স্ট্রাকচার অনুযায়ী প্রথমে roles table এর জন্য একটি Migration File এবং একটি seeder File তৈরি করে ফেলি৷

roles table এর জন্য Migration File তৈরির জন্য নিম্নোক্ত আর্টিসান কমান্ডটি প্রয়োগ করুন :

php artisan make:migration roles

এবার সদ্য তৈরি হওয়া roles Migration File টি কে নিচের মতো করে আপডেট করুন :

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('roles', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('roles');
    }
};

এবং নিম্নোক্ত আর্টিসান কমান্ডের মাধ্যমে Migration File টি রান করুন :

php artisan migrate:refresh --path=database/migrations/Your_Roles_Migrations_File.php

এবার এই সদ্য তৈরি হওয়া roles টেবিলটির জন্য নিম্নোক্ত কমান্ডের মাধ্যমে Role নামক একটি Model তৈরি তৈরি করব।

php artisan make:model Role

এবার এই Role Model ব্যবহার করে roles টেবিল এর জন্য একটি seeder file তৈরি করব।

Seeder File টি তৈরির জন্য নিম্নোক্ত command টি ব্যবহার করুন :

php artisan make:seeder RolesTableSeeder

এবার কিছু dummy Role তৈরির জন্য সদ্য তৈরি হওয়া RolesTableSeeder File এ নিচের মতো করে আপডেট করে নিন :

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\Role;

class RolesTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
       // Clear existing records from the roles table
       Role::truncate();

       // Create sample roles
       $roles = [
           ['name' => 'Admin'],
           ['name' => 'Editor'],
           ['name' => 'User'],
       ];

       // Insert the roles into the roles table
       Role::insert($roles);
    }
}

এবার এই seeder file টি রান করার জন্য নিম্নোক্ত আর্টিসান কমান্ডটি রান করুন :

php artisan db:seed --class=RolesTableSeeder

এখন আপনি দেখতে পাবেন আপনার roles table এ Admin, Editor এবং User নামে তিনটি Role তৈরি হয়েছে।

এবার আমরা role_user table এর জন্য একটি Migration File তৈরি করব যেখানে এ foreign keys হিসেবে role_id এবং user_id থাকবে , যা যথাক্রমে roles এবং users টেবিলের আইডি কলামগুলি নির্দেশ করে। এই foreign keys গুলি roles এবং users টেবিলের মধ্যে সংযোগ স্থাপন করে।

role_user table এর জন্য Migration File তৈরির জন্য নিম্নোক্ত আর্টিসান কমান্ডটি প্রয়োগ করুন :

php artisan make:migration RoleUser

এবার সদ্য তৈরি হওয়া role_user Migration File টি কে নিচের মতো করে আপডেট করুন :

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('role_users', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('role_id');
            $table->unsignedBigInteger('user_id');
            $table->timestamps();

            $table->foreign('role_id')->references('id')->on('roles')->onDelete('cascade');
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('role_users');
    }
};

এবং নিম্নোক্ত আর্টিসান কমান্ডের মাধ্যমে Migration File টি রান করুন :

php artisan migrate:refresh --path=database/migrations/Your_RoleUser_Migrations_File.php

Mastering Laravel with ReactJS Course

এবার এই সদ্য তৈরি হওয়া roles টেবিলটির জন্য নিম্নোক্ত কমান্ডের মাধ্যমে Role নামক একটি Model তৈরি তৈরি করব।

php artisan make:model Role

এবার এই সদ্য তৈরি হওয়া role_user টেবিলটির জন্য নিম্নোক্ত কমান্ডের মাধ্যমে RoleUser নামক একটি Model তৈরি তৈরি করব।

php artisan make:model RoleUser

এবার role_user টেবিল এর জন্য একটি seeder file তৈরি করব।

Seeder File টি তৈরির জন্য নিম্নোক্ত command টি ব্যবহার করুন :

php artisan make:seeder RoleUserTableSeeder

এবার কিছু dummy Role তৈরির জন্য প্রথমে User Model টি কে নিচের মতো করে roles নামক ফাঙ্কশনটি যুক্ত করতে হবে। :

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class User extends Model
{
    use HasFactory;

    protected $fillable = ['username', 'email'];

    public function profile(): HasOne
    {
        return $this->hasOne(Profile::class);
    }

     /**
     * Get the posts for the user.
     */
    public function posts(): HasMany
    {
        return $this->hasMany(Post::class);
    }

     /**
     * Get the roles associated with the user.
     */
    public function roles():BelongsToMany
    {
        return $this->belongsToMany(Role::class, 'role_user');
    }

}

roles() method টি belongsToMany() Method ব্যবহার করে User Model এবং Role মডেলের মধ্যে many-to-many relationship স্থাপন করে। এই Method টি Role model class এবং pivot table (role_user) নির্দিষ্ট করে যা দুটি মডেলকে সংযুক্ত করে।

এবার কিছু dummy Role তৈরির জন্য সদ্য তৈরি হওয়া RoleUserTableSeeder File এ নিচের মতো করে আপডেট করে নিন :

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use App\Models\User;
use App\Models\Role;

class RoleUserTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        // Clear existing records from the role_user table
        DB::table('role_user')->truncate();

        // Retrieve all users and roles
        $users = User::all();
        $roles = Role::all();

        // Assign random roles to each user
        foreach ($users as $user) {
            $user->roles()->attach($roles->random());
        }
    }
}

এবার এই seeder file টি রান করার জন্য নিম্নোক্ত আর্টিসান কমান্ডটি রান করুন :

php artisan db:seed --class=RoleUserTableSeeder

এখন আপনি দেখতে পাবেন role_user টেবিল এ ইউজারদের প্রয়োজনীয় role গুলো এসাইন হয়েছে।

এবার আমরা লারাভেলের many-to-many relationship চেক করার জন্য আমাদের route file এ নিম্নোক্ত কোড গুলো লিখব :

use App\Models\User;
Route::get('/userdetails/{user_id}',function($userId){
    $user = User::find($userId);

    if ($user) {
        $userName = $user->username;
        $userRoles = $user->roles()->pluck('name')->toArray();
    
        // Do something with the user's name and roles
        // For example, print them out
        echo "User Name: $userName" . PHP_EOL;
        echo "User Roles: " . implode(', ', $userRoles) . PHP_EOL;
    } else {
        echo"User not found";
    }
    
});

আবার আপনি যদি একটি Role এর বিপরীতে কতজন ইউজার আছে, তা দেখতে চান , সেক্ষেত্রে আপনাকে Role Model এ user নামক একটি মেথড নিম্নোক্ত উপায়ে ডিফাইন করতে হবে।

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class Role extends Model
{
    use HasFactory;

    public function users(): BelongsToMany
    {
        return $this->belongsToMany(User::class);
    }
}

এবার আপনি আপনার Route এ নিম্নোক্ত উপায়ে চেক করতে পারেন :

use App\Models\Role;

Route::get('/usersbyrole',function(){
    $roleName = 'User';

$role = Role::where('name', $roleName)->first();

if ($role) {
    $users = $role->users;

    foreach ($users as $user) {
        // Do something with each user
        echo "User Name: $user->username" . PHP_EOL;
        // Access other user attributes as needed
    }
} else {
    echo "Role not found";
}
});

আমি মাসুদ আলম, বাংলাদেশের ৩৬ তম Zend Certified Engineer । ২০০৯ সালে কম্পিউটার সাইন্স থেকে বেচেলর ডিগ্রী অর্জন করি। দীর্ঘ ১৫ বছর আমি Winux Soft, SSL Wireless, IBCS-PRIMAX, Max Group, Canadian International Development Agency (CIDA), Care Bangladesh, World Vision, Hellen Keller, Amarbebsha Ltd সহ বিভিন্ন দেশি বিদেশী কোম্পানিতে ডেটা সাইন্স, মেশিন লার্নিং, বিগ ডেটা, ওয়েব ডেভেলপমেন্ট এবং সফটওয়্যার ডেভেলপমেন্ট এর উপর বিভিন্ন লিডিং পজিশন এ চাকরি এবং প্রজেক্ট লিড করি। এছাড়াও বাংলাদেশের ১৮৫ জন জেন্ড সার্টিফাইড ইঞ্জিনিয়ার এর মধ্যে ১২০ এরও অধিক ছাত্র আমার হাতে জেন্ড সার্টিফাইড ইঞ্জিনিয়ার হয়েছেন। বর্তমানে w3programmers ট্রেনিং ইনস্টিটিউট এ PHP এর উপর Professional এবং Advance Zend Certified PHP -8.2 Engineering, Laravel Mastering Course with ReactJS, Python Beginning To Advance with Blockchain, Machine Learning and Data Science, Professional WordPress Plugin Development Beginning to Advance কোর্স করাই। আর অবসর সময়ে w3programmers.com এ ওয়েব টেকনোলজি নিয়ে লেখালেখি করি।

Leave a Reply