Prosta lekcja, wstęp do observera w praktyce. Dodamy sobie kilka kolumn w tabeli notes poprzez migrację. Do dzieła.

Ok, co chcemy mieć:

  • licznik ile razy model został usunięty
  • licznik ile razy model został przywrócony
  • licznik ile razy model miał update

Jak się do tego zabrać:

  • skoro migracja dodaje do już utworzonej tabeli, to metoda down musi cofnąć wszystkie zmiany w up, nie można po prostu tabeli dropnąć ani pustego down zostawić
  • skoro w up dodamy kolumny to w down musimy je dropnąć, wielkiej filozofii nie ma
  • skoro dodajemy do już utworzonej tabeli użyjemy komendy make:migration, staramy się jako tako przestrzegać konwencji nazewniczych, ale nie ufamy Laravelowi aż tak, aby nie użyć flagi –table
  • skoro licznik, to musi być to liczba
  • skoro liczy ile razy coś zostało zrobione, to powinien być unsigned (bez minusowych wartości)
  • skoro dodajemy to tabeli, która A) już istnieje i B) już istnieją w niej rekordy, to pola, które dodajemy muszą być albo nullable, albo mieć default value

Jeżeli tego nie ogarniamy to za daleko wyskoczyliśmy i trzeba przypomnieć sobie podstawy, wszystko już milion razy tłumaczyłem. Oto komenda:

php artisan make:migration add_count_to_notes --table=notes

Teraz napiszmy tę migrację:

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::table('notes', function (Blueprint $table) {
            $table->integer('delete_count')->unsigned()->default(0);
            $table->integer('restore_count')->unsigned()->default(0);
            $table->integer('update_count')->unsigned()->default(0);
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::table('notes', function (Blueprint $table) {
            $table->dropColumn('delete_count');
            $table->dropColumn('restore_count');
            $table->dropColumn('update_count');
        });
    }
};

I wykonajmy ją:

php artisan migrate;

Możemy zobaczyć, że kolumny zostały dodane, zaś wartości tych kolumn to 0. Gdybyśmy zamienili ->default na ->nullable to te już istniejące rekordy miałyby null w miejsce tych kolumn.

Nie możemy natomiast dodać kolumny do już istniejącej tabeli z istniejącymi rekordami, jeżeli to co dodajemy nie jest nullable lub ma default value. Wynika to z prostej logiki – skoro nie można dodać rekordu, który nie ma tych wartości wypełnionych to jakim cudem te rekordy istnieją? I co one tam mają za wartość?

Ok, jak zrobić unsignedInteger? Można też tak:

$table->unsignedInteger('user_id');

Jeszcze bardziej ogarnięci we frameworku mogą zastosować taki zapis:

$table->integer('user_id', false, true);

Mały tip – w dokumentacji (tej łatwiejszej) nic o tym nie ma, jak sprawdzić co to ten true i false?

Napisać w VSCode i najechać myszą. Zobaczymy, że argumenty, które table->integer przyjmuje to:

  • nazwa kolumny
  • auto increment, domyślnie false
  • unsigned, domyślnie false

Auto-increment to jest id na przykład. Jeszcze sobie o tym powiemy.