ল্যারাভেল পিভট টেবিল – নোট অ্যাপে ট্যাগ যোগ করা

এই লেখার পূর্বে আগের দুইটা লেখা ফলো করতে হবেঃ

রিলেশনশিপ ডেটাবেজের সুবিধা হচ্ছে একাধিক টেবিল ব্যবহার করে ডেটা স্টোর করা যায়। সব ডেটা একটা টেবিলে না রেখে আলাদা আলাদা টেবিলে রাখা যায়। আবার দুইটা টেবিলের মধ্যের ডেটা গুলোর সরাসরি রিলেশন না রেখে আলাদা রিলেশন তৈরি করা যায়। এই আলাদা যে টেবিল, তাই হচ্ছে পিভট টেবিল।

উদাহরণ হিসেবে নোট অ্যাপের কথা চিন্তা করি। যেখানে আমরা নোট গুলোতে ট্যাগ যুক্ত করতে চাই। তো নোট একটা টেবিল। ট্যাগের জন্য আলাদা টেবিল তৈরি করব।

এখন একটা নোটে একাধিক ট্যাগ থাকতে পারবে। একই ট্যাগ একাধিক নোটে ব্যবহার করা যাবে। তো কোন নোটে কি কি ট্যাগ রয়েছে, তার জন্য আমরা আলাদা টেবিল ব্যবহার করব। যাকে বলা হয় পিভট টেবিল।

এর আগে আমরা নোট টেবিল এবং মডেল তৈরি করেছি। এবার ট্যাগ মডেল তৈরি করে নেই।

php artisan make:model Tag -m

একটা মাইগ্রেশন তৈরি করে নেই যা আমাদের জন্য ডেটাবেজে note_tag নামে নতুন একটা টেবিল তৈরি করে দিবেঃ

php artisan make:migration create_note_tag_table --create=note_tag

note_tag মাইগ্রেশনঃ

Schema::create('note_tag', function (Blueprint $table) {
    $table->id();
    $table->foreignId('note_id')->constrained()->onDelete('cascade');
    $table->foreignId('tag_id')->constrained()->onDelete('cascade');
    $table->timestamps();
});


Tag মাইগ্রেশনঃ

Schema::create('tags', function (Blueprint $table) {
    $table->id();
    $table->string('name')->unique();
    $table->timestamps();
});

এরপর ডেটাবেজ মাইগ্রেট করে নিবঃ

php artisan migrate

Note মডেলে ট্যাগ রিলেশনশিপঃ

    public function tags()
    {
        return $this->belongsToMany(Tag::class);
    }

Tag মডেলে নোট রিলেশনশিপঃ

class Tag extends Model
{
    protected $fillable = ['name'];

    public function notes()
    {
        return $this->belongsToMany(Note::class);
    }
}

নোটে ট্যাগ যুক্ত করা

এবার আমরা নোট তৈরি করার সময় ট্যাগ যুক্ত করতে পারব। ফরমে একটা টেক্সট ইনপুট যুক্ত করে নিন। যেখানে ট্যাগ গুলো কমা সেফারেট করে যোগ করা যাবে।

<input type="text" id="tags" name="tags" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" placeholder="Tags, sepeate using comma.">

এবার store মেথড এভাবে লিখিঃ

    public function store(Request $request)
    {
        $data = $request->validate([
            'title' => ['required', 'string'],
            'note' => ['required', 'string'],
            'tags' => 'nullable|string'
        ]);

        $user = Auth::user();

        $note = $user->notes()->create([
            'title' => $data['title'],
            'note' => $data['note'],
        ]);

        // Process the tags if any are provided
        if (!empty($data['tags'])) {
            // Split the tags string into an array
            $tagNames = explode(',', $data['tags']);

            // Trim whitespace and create/find each tag
            $tagIds = [];
            foreach ($tagNames as $tagName) {
                $tag = Tag::firstOrCreate(['name' => trim($tagName)]);
                $tagIds[] = $tag->id;
            }

            // Attach the tags to the note
            $note->tags()->attach($tagIds);
        }

উপরে store মেথডে আমরা প্রথমে ট্যাগ গুলো আলাদা করেছি। যদি ডেটাবেজের tags টেবিলে নির্দিষ্ট ট্যাগ না থাকে, তাহলে ঐ ট্যাগ যুক্ত করেছি। এবং নোটের সাথে ট্যাগ গুলো যুক্ত করেছি।

এখন চাইলে আমরা নোটের সাথে থাকা ট্যাগ গুলো দেখাতে পারিঃ

        <h4>Tags:</h4>
        @if($note->tags->isEmpty())
            <p>No tags associated with this note.</p>
        @else
            <ul>
                @foreach($note->tags as $tag)
                    <li>{{ $tag->name }}</li>
                @endforeach
            </ul>
        @endif

ফাইনালি যেন কেউ লগিন করা ছাড়া New নোট তৈরি করতে না পারেঃ

Route::middleware(["auth","verified"])->group(function () {
    Route::resource('note', NoteController::class);
});

লগইন ইউজারের জন্য এবং লগআউট ইউযারের জন্য ন্যাভিগেশন লিঙ্ক এভাবে দেখাতে পারিঃ

<nav>
    <ul>
        <!-- Other navigation links -->

        @auth
            <!-- User is logged in -->
            <li><a href="{{ route('profile') }}">Profile</a></li>
            <li><a href="{{ route('logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();">Logout</a></li>
            
            <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
                @csrf
            </form>
        @else
            <!-- User is not logged in -->
            <li><a href="{{ route('login') }}">Login</a></li>
            <li><a href="{{ route('register') }}">Register</a></li>
        @endauth
    </ul>
</nav>

হয়ে গেলো একটা পূর্ণাজ্ঞ নোট অ্যাপ। যেখানে ব্যবহারকারী নোটে বিভিন্ন ট্যাগ যুক্ত করতে পারবে। এরপর আপনি চাইলে ট্যাগ অনুসারে নোট দেখাতে পারে।

Leave a Reply