Inserting ,Updating Deleting and Pruning Laravel Models

Inserting Updating-and-Deleting-Laravel-Model

Laravel-এ, Eloquent যা মূলত একটি Object-Relational Mapping (ORM) যা আপনাকে raw SQL কোয়েরি লেখার পরিবর্তে PHP সিনট্যাক্স ব্যবহার করে আপনার ডাটাবেসের সাথে ইন্টারঅ্যাক্ট করতে দেয়। Eloquent common database operations যেমন inserting, updating এবং রেকর্ডগুলি deleting এর কাজ সহজ করে তোলে।

Inserts

ডাটাবেসে একটি নতুন রেকর্ড insert করতে, আপনাকে একটি নতুন model instance কে instantiate করতে হবে এবং model টিতে attributes গুলি সেট করতে হবে । তারপর, model instance এ save method কল করতে হবে :

<?php
 
namespace App\Http\Controllers;
 
use App\Http\Controllers\Controller;
use App\Models\Flight;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
 
class FlightController extends Controller
{
    /**
     * Store a new flight in the database.
     */
    public function store(Request $request): RedirectResponse
    {
        // Validate the request...
 
        $flight = new Flight;
 
        $flight->name = $request->name;
 
        $flight->save();
 
        return redirect('/flights');
    }
}

এই উদাহরণে, আমরা incoming HTTP request থেকে name attribute টিকে App\Models\Flight মডেল ইনস্ট্যান্সের নামের বৈশিষ্ট্যে বরাদ্দ করি। যখন আমরা save method কল করি, তখন একটি রেকর্ড ডাটাবেসে ঢোকানো হবে। save method কল করা হলে মডেলের created_at এবং updated_at টাইমস্ট্যাম্পগুলি স্বয়ংক্রিয়ভাবে সেট হয়ে যাবে, তাই সেগুলিকে ম্যানুয়ালি সেট করার দরকার নেই।

এছাড়াও , আপনি একটি single PHP statement ব্যবহার করে একটি নতুন মডেল “save” করতে create method ব্যবহার করতে পারেন:

use App\Models\Flight;
 
$flight = Flight::create([
    'name' => 'London to Paris',
]);

Note: create method ব্যবহার করার আগে, আপনাকে আপনার মডেল ক্লাসে একটি fillable বা guarded property নির্দিষ্ট করতে হবে। এই property গুলি required কারণ সমস্ত ইলোকুয়েন্ট মডেলগুলি ডিফল্টরূপে mass assignment vulnerabilities বিরুদ্ধে protected.

mass assignment সম্পর্কে আরও জানতে, অনুগ্রহ করে mass assignment documentation দেখুন।

Updates

আপনি যদি ডাটাবেসে ইতিমধ্যে বিদ্যমান মডেলগুলিকে আপডেট করতে চান , তাহলেও আপনি save method টি ব্যবহার করতে পারেন। একটি মডেল আপডেট করতে,প্রথমে আপনাকে এটি retrieve করতে হবে তারপর আপনি যা আপডেট করতে চান এমন যেকোনো attributes গুলো সেট করুন৷ তারপর, আপনি মডেলের save method কল করতে হবে। তখন , updated_at টাইমস্ট্যাম্পটি স্বয়ংক্রিয়ভাবে আপডেট হবে, তাই ম্যানুয়ালি এর মান সেট করার প্রয়োজন নেই:

use App\Models\Flight;
 
$flight = Flight::find(1);
 
$flight->name = 'Paris to London';
 
$flight->save();

Mass Updates

Laravel Eloquent “mass updates” নামে একটি feature প্রদান করে যা আপনাকে কোডের একটি লাইন ব্যবহার করে একবারে একটি ডাটাবেস টেবিলে একাধিক রেকর্ড আপডেট করতে দেয়। এটি উপযোগী হয় যখন আপনি একই ডেটা সহ প্রচুর সংখ্যক রেকর্ড আপডেট করতে চান বা যখন আপনি একাধিক রেকর্ডে একযোগে একাধিক fields আপডেট করতে চান।

প্রদত্ত query এর সাথে মেলে এমন মডেলগুলির বিরুদ্ধেও আপডেটগুলি রান করতে পারেন ৷ এই উদাহরণে, যে সমস্ত ফ্লাইট active আছে এবং San Diego গন্তব্য আছে সেগুলিকে delayed হিসাবে চিহ্নিত করা হবে:

Flight::where('active', 1)
      ->where('destination', 'San Diego')
      ->update(['delayed' => 1]);

update method টি column এবং value pairs একটি অ্যারে আশা করে যে কলামগুলিকে আপডেট করা উচিত। update method টি আপনাকে affected rows সংখ্যা প্রদান করে।

Examining Attribute Changes

Eloquent আপনার মডেলের অভ্যন্তরীণ অবস্থা পরীক্ষা করার জন্য isDirty, isClean এবং wasChanged methods গুলি প্রদান করে এবং নির্ধারণ করে যে মডেলটি আসলে পুনরুদ্ধার করার সময় থেকে এর attributes গুলি কিধরনের পরিবর্তন হয়েছে।

isDirty method নির্ধারণ করে যে মডেলটি retrieved করার পর থেকে মডেলের কোনো attributes পরিবর্তন করা হয়েছে কিনা। isDirty method এ আপনি একটি নির্দিষ্ট attributes এর নাম বা attributes গুলির একটি অ্যারে পাস করতে পারেন , যা আপনার জন্য চেক করবে যে কোনো attributes “dirty” কিনা ?আবার মডেলটি retrieved করার পর থেকে একটি attribute অপরিবর্তিত রয়েছে কিনা তা isClean method নির্ধারণ করবে। এই method টি একটি optional attribute argument ও গ্রহণ করে:

use App\Models\User;
 
$user = User::create([
    'first_name' => 'Taylor',
    'last_name' => 'Otwell',
    'title' => 'Developer',
]);
 
$user->title = 'Painter';
 
$user->isDirty(); // true
$user->isDirty('title'); // true
$user->isDirty('first_name'); // false
$user->isDirty(['first_name', 'title']); // true
 
$user->isClean(); // false
$user->isClean('title'); // false
$user->isClean('first_name'); // true
$user->isClean(['first_name', 'title']); // false
 
$user->save();
 
$user->isDirty(); // false
$user->isClean(); // true

wasChanged method নির্ধারণ করে যে current request cycle এর মধ্যে মডেলটি শেষবার সংরক্ষণ করার সময় কোনো attributes পরিবর্তন করা হয়েছে কিনা। প্রয়োজনে, আপনি একটি বিশেষ attribute পরিবর্তন করা হয়েছে কিনা তা দেখতে একটি attribute এর নাম পাস করতে পারেন:

$user = User::create([
    'first_name' => 'Taylor',
    'last_name' => 'Otwell',
    'title' => 'Developer',
]);
 
$user->title = 'Painter';
 
$user->save();
 
$user->wasChanged(); // true
$user->wasChanged('title'); // true
$user->wasChanged(['title', 'slug']); // true
$user->wasChanged('first_name'); // false
$user->wasChanged(['first_name', 'title']); // true

getOriginal method টি দিয়ে কোনো মডেল retrieved করার পর থেকে উক্ত মডেলের কোনো পরিবর্তন হয়েছে কিনা তা জানার জন্য নির্বিশেষে মডেলের মূল attributes সমন্বিত একটি অ্যারে প্রদান করে। প্রয়োজনে, আপনি একটি নির্দিষ্ট attribute এর আসল মান পেতে একটি নির্দিষ্ট attribute এর নাম পাস করতে পারেন:

$user = User::find(1);
 
$user->name; // John
$user->email; // john@example.com
 
$user->name = "Jack";
$user->name; // Jack
 
$user->getOriginal('name'); // John
$user->getOriginal(); // Array of original attributes...

Mastering Laravel with ReactJS Course

Mass Assignment

Mass Assignment হল লারাভেলের একটি feature যা আপনাকে key-value pairs অ্যারে পাস করে একটি মডেলের একসাথে একাধিক attributes গুলিকে সহজেই তৈরি বা আপডেট করতে দেয়। প্রতিটি attribute আলাদাভাবে সেট করার পরিবর্তে এটি একসাথে অনেকগুলি attribute তৈরি বা আপডেট করার একটি দারুন উপায়।

আপনি একটি single PHP statement ব্যবহার করে একটি নতুন মডেল “save” করতে create method ব্যবহার করতে পারেন। inserted model instance টি আপনাকে একটি method দ্বারা return দেওয়া হবে:

use App\Models\Flight;
 
$flight = Flight::create([
    'name' => 'London to Paris',
]);

যাইহোক, create method ব্যবহার করার আগে, আপনাকে আপনার মডেল ক্লাসে একটি fillable বা guarded property নির্দিষ্ট করতে হবে। এই properties গুলি প্রয়োজনীয় কারণ সমস্ত Eloquent models গুলি ডিফল্টরূপে mass assignment vulnerabilities বিরুদ্ধে সুরক্ষিত।

একটি mass assignment vulnerability ঘটে যখন একজন ইউজার একটি unexpected HTTP request field পাস করে এবং সেই field টি আপনার ডাটাবেসের একটি কলাম পরিবর্তন করে যা আপনি আশা করেননি। উদাহরণস্বরূপ, একটি মালিসিয়াস ইউজার একটি HTTP request এর মাধ্যমে একটি is_admin প্যারামিটার পাঠাতে পারে, যা তারপরে আপনার মডেলের create method এ প্রেরণ করা হয়, যা ব্যবহারকারীকে নিজেকে administrator এর কাছে পর্যন্ত পৌঁছানোর অনুমতি দেয়।

তাহলে চলুন, আপনি মডেলের কোন attributes গুলিকে mass assignable করতে চান তা নির্ধারণ করা উচিত। আপনি মডেলে $fillable property ব্যবহার করে এটি করতে পারেন। উদাহরণ স্বরূপ, আসুন আমাদের Flight model এর name attribute কে mass assignable করে তুলি:

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class Flight extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['name'];
}

যখন একবার আপনি নির্দিষ্ট করবেন যে কোন attributes গুলি mass assignable, তখন আপনি ডাটাবেসে একটি নতুন রেকর্ড সন্নিবেশ করার জন্য create method টি ব্যবহার করতে পারেন। create method টি নতুন তৈরি মডেল এর instance রিটার্ন করে:

$flight = Flight::create(['name' => 'London to Paris']);

আপনার যদি ইতিমধ্যেই একটি model instance থাকে, তাহলে আপনি attributes গুলির একটি অ্যারে দিয়ে এটি পূরণ করতে ব্যবহার করতে পারেন:

$flight->fill(['name' => 'Amsterdam to Frankfurt']);

Mass Assignment & JSON Columns

JSON কলাম বরাদ্দ করার সময়, প্রতিটি কলামের mass assignable key আপনার মডেলের $fillable অ্যারেতে নির্দিষ্ট করা আবশ্যক। সিকিউরিটি এর জন্য, guarded property ব্যবহার করার সময় লারাভেল nested JSON attributes গুলি আপডেট করা সমর্থন করে না:

/**
 * The attributes that are mass assignable.
 *
 * @var array
 */
protected $fillable = [
    'options->enabled',
];

Allowing Mass Assignment

আপনি যদি আপনার সমস্ত attributes কে mass assignable করতে চান তবে আপনি আপনার মডেলের $guarded property টিকে একটি খালি অ্যারে হিসাবে সংজ্ঞায়িত করতে পারেন। আপনি যদি আপনার মডেলকে unguard করতে চান, তাহলে আপনাকে সর্বদা ইলোকুয়েন্টস fill, create এবং update method এপাস করা অ্যারেগুলিকে hand-craft করার জন্য বিশেষ যত্ন নেওয়া উচিত:

/**
 * The attributes that aren't mass assignable.
 *
 * @var array
 */
protected $guarded = [];

Mass Assignment Exceptions

বাই ডিফল্ট , $fillable অ্যারেতে অন্তর্ভুক্ত নয় এমন attributes গুলি mass-assignment operations করার সময় silently discarded করা হয়। production এ , এটি প্রত্যাশিত আচরণ; যাইহোক, local development এর সময় এটি বিভ্রান্তির কারণ হতে পারে কেন মডেল পরিবর্তনগুলি কার্যকর হচ্ছে না।

আপনি যদি চান, আপনি লারাভেলকে একটি exception throw করার নির্দেশ দিতে পারেন যখন একটি unfillable attribute কে fill করার চেষ্টা করার সময় preventSilentlyDiscardingAttributes method ব্যবহার করে। সাধারণত, এই method টি আপনার application’s এর service provider এর boot method এর মধ্যে চালু করা উচিত:

use Illuminate\Database\Eloquent\Model;
 
/**
 * Bootstrap any application services.
 */
public function boot(): void
{
    Model::preventSilentlyDiscardingAttributes($this->app->isLocal());
}

firstOrCreate() Method

Laravel-এ firstOrCreate() method আপনাকে ডাটাবেস থেকে প্রথম রেকর্ডটি retrieve করতে দেয় যা প্রদত্ত attributes সাথে match করে, অথবা যদি কোনো match করা রেকর্ড না পাওয়া যায় তাহলে একটি নতুন রেকর্ড তৈরি করে । এই method টি উপযোগী হতে পারে যখন আপনি একটি নতুন তৈরি করার আগে একটি রেকর্ড ইতিমধ্যেই ডাটাবেসে বিদ্যমান আছে কিনা তা পরীক্ষা করতে চান।

firstOrCreate() method টি কীভাবে ব্যবহার করবেন তার একটি উদাহরণ এখানে রয়েছে:

use App\Models\user;

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

    $user = User::firstOrCreate([
        'email' => 'johndoe@example.com'
    ], [
        'name' => 'John Doe',
        'phone'=>'01788229988',
        'age' =>30.5,
    ]);

    echo $user->name,"<br>",$user->phone,"<br>",$user->age;

});

এই উদাহরণে, johndoe@example.com-এর ইমেলের মাধ্যমে প্রথম ব্যবহারকারীর রেকর্ড retrieve করতে আমরা firstOrCreate() method ব্যবহার করছি। যদি একটি ম্যাচিং রেকর্ড পাওয়া যায়, এটি ফেরত দেওয়া হবে. যদি কোনো ম্যাচিং রেকর্ড পাওয়া না যায়, তাহলে নির্দিষ্ট attributes (name, phone এবং age) সহ একটি নতুন User instance তৈরি করা হবে এবং ডাটাবেসে সংরক্ষণ করা হবে।

লক্ষ্য করুন যে firstOrCreate()-এর প্রথম আর্গুমেন্টে সার্চ করার জন্য অ্যাট্রিবিউট রয়েছে এবং দ্বিতীয় আর্গুমেন্টে নতুন রেকর্ড তৈরি হলে সেট করার অ্যাট্রিবিউট রয়েছে। যদি আপনি একটি দ্বিতীয় argument প্রদান না করেন, মডেলের জন্য ডিফল্ট মান তার পরিবর্তে ব্যবহার করা হবে।

firstOrCreate() method টি প্রতিটি অপারেশনের জন্য আলাদা queries না লিখেই ডাটাবেসে একটি রেকর্ড বিদ্যমান আছে কিনা তা পরীক্ষা করার এবং প্রয়োজনে একটি নতুন রেকর্ড তৈরি করার একটি সুবিধাজনক উপায়।

updateOrCreate Method

Laravel-এ updateOrCreate() method টি আপনাকে ডাটাবেসে একটি রেকর্ড আপডেট করতে দেয় যদি এটি বিদ্যমান থাকে, আর যদি এটি বিদ্যমান না থাকে তাহলে একটি নতুন রেকর্ড তৈরি করে । এই method টি উপযোগী হতে পারে যখন আপনাকে একটি রেকর্ড আপডেট করতে হবে যদি এটি বিদ্যমান থাকে, অথবা এটি না থাকলে একটি নতুন তৈরি করতে হয়, প্রতিটি অপারেশনের জন্য আলাদা queries না লিখে।

কিভাবে updateOrCreate() method টি ব্যবহার করতে হয় তার একটি উদাহরণ এখানে দেওয়া হল:

use App\Models\user;

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

    $user = User::updateOrCreate([
        'email' => 'johndoe@example.com'
    ], [
        'name' => 'John Doe',
        'phone'=>'01755229988',
        'age' =>30.5,
    ]);

    echo $user->name,"<br>",$user->phone,"<br>",$user->age;

});

এই উদাহরণে, আমরা যদি ইউজার ইনফরমেশন বিদ্যমান থাকে তাহলে johndoe@example.com- ইমেলের মাধ্যমে ইউজারের রেকর্ড আপডেট করতে updateOrCreate() method ব্যবহার করছি, অথবা নির্দিষ্ট attributes (name, phone এবং age) সহ একটি নতুন User instance তৈরি করুন এবং এটি সংরক্ষণ করুন ডাটাবেস যদি এটি বিদ্যমান না থাকে।

তবে এখানে মনে রাখতে হবে যে updateOrCreate()-এর প্রথম argument হিসেবে সার্চ করার জন্য attributes রয়েছে এবং দ্বিতীয় আর্গুমেন্টে আপডেট বা তৈরি করার অ্যাট্রিবিউট রয়েছে। রেকর্ড বিদ্যমান থাকলে, এটি নির্দিষ্ট attributes সাথে আপডেট করা হবে। এটি বিদ্যমান না থাকলে, নির্দিষ্ট attributes গুলির সাথে একটি নতুন রেকর্ড তৈরি করা হবে।

updateOrCreate() method টি একটি রেকর্ড আপডেট করার একটি সুবিধাজনক উপায় যদি এটি বিদ্যমান থাকে, অথবা এটি না থাকলে একটি নতুন তৈরি করে, আর এর জন্য প্রতিটি অপারেশনের জন্য আলাদা queries লিখে না ।

Upserts

লারাভেলের upsert() Method টি updateOrCreate() Method এর মতোই যা আপনাকে ডাটাবেসে রেকর্ড আপডেট করার সুযোগ দেয় যদি সেগুলি বিদ্যমান থাকে, আর যদি সেগুলি বিদ্যমান না থাকে তবে নতুন রেকর্ড তৈরি করার সুযোগ দেয় । যাইহোক, এই দুটি পদ্ধতির মধ্যে কিছু মূল পার্থক্য রয়েছে।

upsert() এবং updateOrCreate() এর মধ্যে প্রধান পার্থক্য হল upsert() আপনাকে একটি single query তে multiple records আপডেট করতে দেয়, যেখানে updateOrCreate() শুধুমাত্র একই সময়ে একটি রেকর্ড আপডেট করে বা তৈরি করে। upsert() large number রেকর্ড আপডেট করার জন্য আরও efficient হতে পারে, যখন updateOrCreate() একটি সময়ে একটি একক রেকর্ড আপডেট বা তৈরি করার জন্য আরও উপযুক্ত।

এই দুটি methods এর মধ্যে আরেকটি মূল পার্থক্য হল তারা যেভাবে primary key values গুলি handle করার উপায়। updateOrCreate() অনুমান করে যে primary key value টি ইতিমধ্যেই বিদ্যমান এবং সংশ্লিষ্ট রেকর্ডটি আপডেট করে যদি এটি থাকে, বা এটি না থাকলে একটি নতুন primary key মান সহ একটি নতুন রেকর্ড তৈরি করে। অন্য দিকে, upsert(), আপনাকে primary key value এর উপর ভিত্তি করে একটি রেকর্ড সন্নিবেশ বা আপডেট করতে হবে কিনা তা নির্দিষ্ট করতে দেয়। আপডেট প্রক্রিয়ার উপর আপনার আরও সূক্ষ্ম নিয়ন্ত্রণের প্রয়োজন হলে এটি কার্যকর হতে পারে।

কিভাবে upsert() পদ্ধতি ব্যবহার করতে হয় তার একটি উদাহরণ এখানে দেওয়া হল:

$data = [
    [
        'id' => 1,
        'name' => 'John Doe',
        'email' => 'johndoe@example.com',
    ],
    [
        'id' => 2,
        'name' => 'Jane Doe',
        'email' => 'janedoe@example.com',
    ],
];

User::upsert($data, ['id'], ['name', 'email']);

এই উদাহরণে, আমরা id field এর উপর ভিত্তি করে দুটি ইউজার রেকর্ড আপডেট বা তৈরি করতে User model এ upsert() method ব্যবহার করেছি। যদি একটি ম্যাচিং আইডি ভ্যালু সহ একটি রেকর্ড বিদ্যমান থাকে, তবে এটি নির্দিষ্ট নাম এবং ইমেল ভ্যালু গুলির সাথে আপডেট করা হবে৷ আর বিদ্যমান না থাকলে, এটি নির্দিষ্ট মানগুলির সাথে একটি নতুন রেকর্ড তৈরি করা হবে।

Deleting Models

একটি মডেল ডিলেট করে ফেলার জন্য, আপনি model instance এর delete method কল করতে পারেন:

use App\Models\Flight;
 
$flight = Flight::find(1);
 
$flight->delete();

আপনি model’s associated database records রেকর্ড মুছে ফেলার জন্য truncate method কল করতে পারেন। truncate method টি মডেলের সংশ্লিষ্ট টেবিলে যেকোন auto-incrementing ID গুলো পুনরায় সেট করবে:

Flight::truncate();

Deleting An Existing Model By Its Primary Key

উপরের উদাহরণে, আমরা ডিলিট মেথড কল করার আগে ডাটাবেস থেকে মডেলটি retrieve করছি। যাইহোক, যদি আপনি মডেলের primary key জানেন, আপনি destroy method কল করে স্পষ্টভাবে retrieve না করেই মডেলটি মুছে ফেলতে পারেন। একক primary key গ্রহণ করার পাশাপাশি, ধ্বংস পদ্ধতি একাধিক primary key , primary key গুলির একটি অ্যারে, বা primary key গুলির একটি collection গ্রহণ করবে:

Flight::destroy(1);
 
Flight::destroy(1, 2, 3);
 
Flight::destroy([1, 2, 3]);
 
Flight::destroy(collect([1, 2, 3]));

Mastering Laravel with ReactJS Course

Deleting Models Using Queries

অবশ্যই, আপনি আপনার query’s criteria এর সাথে মেলে এমন সমস্ত মডেল মুছে ফেলার জন্য একটি Eloquent query তৈরি করতে পারেন। এই উদাহরণে, আমরা inactive হিসাবে চিহ্নিত সমস্ত ফ্লাইট ডিলিট করে ফেলব। mass updates, mass deletes এর মতো, মোছা মডেলগুলির জন্য মডেল ইভেন্টগুলি প্রেরণ করবে না:

$deleted = Flight::where('active', 0)->delete();

Soft Deleting

আপনার ডাটাবেস থেকে রেকর্ডগুলি সম্পূর্ণ মুছে ফেলার পরিবর্তে , Eloquent দিয়ে মডেলগুলিকে “soft delete” করতে পারেন। যখন মডেলগুলি soft deleted হয়, তখন সেগুলি আসলে আপনার ডাটাবেস থেকে রিমুভ হয় না। বরং, মডেলটিতে একটি deleted_at অ্যাট্রিবিউট সেট করা হয় যে তারিখ এবং সময় নির্দেশ করে যে মডেলটি “delete করা হয়েছে”। আপনি যদি একটি মডেলের জন্য সফট ডিলিট সুবিধা রাখতে চান, তাহলে মডেলটিতে আপনাকে Illuminate\Database\Eloquent\SoftDeletes trait যোগ করতে হবে:

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
 
class Flight extends Model
{
    use SoftDeletes;
}

এক্ষেত্রে SoftDeletes attribute স্বয়ংক্রিয়ভাবে আপনার জন্য একটি DateTime / Carbon instance deleted_at attribute টি কাস্ট করবে।

আর এর জন্য আপনার ডাটাবেস টেবিলে deleted_at column টিও যোগ করতে হবে। Laravel schema builder এই কলামটি তৈরি করতে পারেন।

চলুন একটি প্রাকটিক্যাল উদাহরণ দেখে নেওয়া যাক:

প্রথমে নিম্নোক্ত কম্যান্ড ব্যবহার করে একটি Migration File তৈরি করুন :

php artisan make:migration softdeletesforusers

এবার সদ্য তৈরি মাইগ্রেশন ফাইলটি নিচের মতো করে আপডেট করুন :

<?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::table('users', function (Blueprint $table) {
            $table->softDeletes();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropSoftDeletes();
        });
    }
};

এখন, যখন আপনি মডেলে delete method কল করবেন, deleted_at column টি current date এবং time সেট করা হবে। তবে মডেলের ডাটাবেস রেকর্ড টেবিলে রেখে দেওয়া হবে। সফ্ট ডিলিট ব্যবহার করে এমন একটি মডেলকে querying করার সময়, soft deleted model গুলি স্বয়ংক্রিয়ভাবে সমস্ত ক্যোয়ারী ফলাফল থেকে বাদ দেওয়া হবে৷

এবার নিম্নোক্ত কমান্ড দিয়ে মাইগ্রেশন ফাইলটি রান করুন:

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

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

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class User extends Model
{
    use HasFactory,SoftDeletes;
}

এবার আপনার UserController কে নিচের মতো করে আপডেট করে নিন:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;

class UserController extends Controller
{
    public function index(){
        $users = User::whereNull('deleted_at')->get();
        foreach($users as $user){
            echo "Id: ",$user->id;
            echo "  Name: ",$user->name;
            echo "<br>";
        }
    }

    public function getById(Request $request,$id){
        $user = User::where('id', $id)->whereNull('deleted_at')->first();

        echo $user->name;
    }
     /**
     * Delete a user.
     */
    public function delete(Request $request, $id)
    {
        $user = User::find($id);

        if ($user) {
            $user->delete(); // Soft delete the user
            return "User Delete Success";
        } else {
            return "User Delete Fail!";
        }
    }

    /**
     * Restore a deleted user.
     */
    public function restore(Request $request, $id)
    {
        $user = User::withTrashed()->find($id);

        if ($user) {
            $user->restore(); // Restore the soft deleted user
            return 'User restored successfully.';
        } else {
            return 'User not found.';
        }
    }

    /**
     * Permanently delete a user.
     */
    public function forceDelete(Request $request, $id)
    {
        $user = User::withTrashed()->find($id);

        if ($user) {
            $user->forceDelete(); // Permanently delete the user
            return 'User permanently deleted.';
        } else {
            return 'User not found.';
        }
    }
}


সর্বশেষ আপনার route গুলো নিচের মতো করে ডিফাইন করে নিন :

use App\Http\Controllers\UserController;

Route::get('/users', [UserController::class, 'index'])->name('users.list');
Route::get('/users/{id}/get', [UserController::class, 'getById'])->name('users.get');
Route::get('/users/{id}/delete', [UserController::class, 'delete'])->name('users.delete');
Route::get('/users/{id}/restore', [UserController::class, 'restore'])->name('users.restore');
Route::get('/users/{id}/force-delete', [UserController::class, 'forceDelete'])->name('users.forceDelete');

Pruning Models

Model pruning শব্দ দুটির মধ্যে Pruning শব্দের অর্থ হল ছাঁটাই করা। Model pruning হল লারাভেলের একটি ফীচার যা আপনাকে নির্দিষ্ট শর্ত বা নিয়মের উপর ভিত্তি করে আপনার ডাটাবেস টেবিল থেকে রেকর্ডগুলি স্বয়ংক্রিয়ভাবে মুছে ফেলতে বা রিমুভ করতে দেয়।

Model pruning লারাভেলের একটি দরকারী ফীচার যা আপনাকে পুরানো বা অপ্রয়োজনীয় ডেটা স্বয়ংক্রিয়ভাবে মুছে বা মুছে ফেলার মাধ্যমে আরও দক্ষতার সাথে আপনার ডেটাবেস পরিচালনা করতে সহায়তা করতে পারে। এটি এমন অ্যাপ্লিকেশনগুলির জন্য বিশেষভাবে সহায়ক হতে পারে যেগুলি প্রচুর পরিমাণে ডেটা নিয়ে কাজ করে এবং স্থান এবং সংস্থানগুলি খালি করার জন্য তাদের ডেটাবেসকে পর্যায়ক্রমে পরিষ্কার করতে হয়।

ধরুন আপনার কাছে একটি পোস্ট মডেল আছে যা ব্লগ পোস্টগুলিকে রিপ্রেজেন্ট করে এবং আপনি 30 দিনের বেশি পুরানো সমস্ত পোস্ট স্বয়ংক্রিয়ভাবে মুছে ফেলতে চান৷

তো চলুন তার আগে এমন একটা Post Migration File তৈরি করি , যেটির পোস্ট গুলো ৩০ দিনের পুরোনো হবে। প্রথমে নিম্নোক্ত কমান্ডের মাধ্যমে Post Model এবং তার জন্য একটি Migration File এবং Seeder File টি তৈরি করে ফেলুন :

php artisan make:model Post -ms

এবার আপনার সদ্য তৈরি হওয়া 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->string('title');
            $table->text('content');
            $table->timestamps();
        });
    }

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

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

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

এখন আমরা উক্ত টেবিল এ এমন কিছু ডেটা insert করব , যেগুলোর Date টা অন্তত পক্ষে ৩০ দিনের পুরোনো হবে। আর এর জন্য আপনার Seeder File টি নিচের মতো করে আপডেট করে নিন :

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\Post;
use Carbon\Carbon;

class PostSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        $now = Carbon::now();
        $oldDate = $now->subDays(31);

        $posts = [
            [
                'title' => 'First Post',
                'content' => 'This is the content of the first post.',
                'created_at' => $oldDate,
                'updated_at' => $oldDate,
            ],
            [
                'title' => 'Second Post',
                'content' => 'This is the content of the second post.',
                'created_at' => $oldDate,
                'updated_at' => $oldDate,
            ],
            [
                'title' => 'Third Post',
                'content' => 'This is the content of the Third post.',
                'created_at' => $oldDate,
                'updated_at' => $oldDate,
            ],
            [
                'title' => 'Fourth Post',
                'content' => 'This is the content of the Fourth post.',
                'created_at' => $oldDate,
                'updated_at' => $oldDate,
            ],
            [
                'title' => 'Fifth Post',
                'content' => 'This is the content of the Fifth post.',
                'created_at' => $oldDate,
                'updated_at' => $oldDate,
            ],
        ];

        foreach ($posts as $post) {
            Post::create($post);
        }
    }
}

এবার নিম্নোক্ত কমান্ডের মাধ্যমে উপরোক্ত seeder file টি রান করুন:

php artisan db:seed --class=PostSeeder

তো হয়ে গেল ৩০ দিনের পুরাতন ডাটা ইনসার্ট করা। এখন আপনার Post Model টিকে নিচের মতো করে আপডেট করে নিন :

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Prunable;

class Post extends Model
{
    use HasFactory,Prunable;

    /**
     * Get the prunable model query.
     */
    public function prunable(): Builder
    {
        return static::where('created_at', '<=', now()->subMonth());
    }
}

এবার যদি আপনি নিম্নোক্ত কমান্ড রান করেন, আপনি লক্ষ্য করবেন , আপনার যেসব পোস্ট ৩০ দিনের পুরোনো সেগুলো স্বয়ংক্রিয়ভাবে ডিলিট হয়ে গেছে :

php artisan model:prune

Mastering Laravel with ReactJS Course

Model গুলিকে Prunable হিসাবে চিহ্নিত করার সময়, আপনি মডেলটিতে একটি pruning() method ও ডিফাইন করতে পারেন। মডেলটি মুছে ফেলার পূর্বে এই method টি call হবে। মডেলটিকে স্থায়ীভাবে ডাটাবেস থেকে মুছে ফেলার আগে এই method টি মডেলের সাথে যুক্ত যেকোন অতিরিক্ত রিসোর্সেস যেমন stored files এবং Foreign Key মুছে ফেলার জন্য উপযোগী হতে পারে:

  protected function pruning(): void
    {
        echo 'Pruning'.$this->title.PHP_EOL;
    }

আপনার prunable model কনফিগার করার পরে, আপনার অ্যাপ্লিকেশনের App\Console\Kernel ক্লাসে model:prune Artisan command টি নির্ধারণ করে দিতে পারেন। আপনি উপযুক্ত ব্যবধান interval করতে স্বাধীন যে এই কমান্ডটি কখন চালানো উচিত:

/**
 * Define the application's command schedule.
 */
protected function schedule(Schedule $schedule): void
{
    $schedule->command('model:prune')->daily()->at('23:59');
}

এছাড়া পিছন থেকে , model:prune কমান্ডটি স্বয়ংক্রিয়ভাবে আপনার অ্যাপ্লিকেশনের app/Models ডিরেক্টরির মধ্যে “Prunable” মডেল সনাক্ত করবে। যদি আপনার মডেলগুলি একটি ভিন্ন লোকেশনে থাকে, আপনি model class এর নাম গুলোকে নির্দিষ্ট করতে –model option টি ব্যবহার করতে পারেন:

$schedule->command('model:prune', [
    '--model' => [Address::class, Flight::class],
])->daily();

আপনি যদি অন্য সমস্ত শনাক্ত করা মডেল pruned করার সময় নির্দিষ্ট মডেলগুলিকে pruned থেকে বাদ দিতে চান তবে আপনি –except option টি ব্যবহার করতে পারেন:

$schedule->command('model:prune', [
    '--except' => [Address::class, Flight::class],
])->daily();

আপনি –pretend option এর সাথে model:prune কমান্ডটি এক্সেকিউট করে আপনার prunable query test করতে পারেন। pretend করার সময়, model:prune command টি সহজভাবে রিপোর্ট করবে যে কমান্ডটি আসলে চালানো হলে কত রেকর্ড pruned বা ছাঁটাই হবে:

php artisan model:prune --pretend

আমি মাসুদ আলম, বাংলাদেশের ৩৬ তম 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