Przypominamy sobie konwencje nazewnicze Laravela. Lekcja konieczna, aby ruszyć dalej z materiałem, musimy to sobie wyjaśnić.

Ok, co taka komenda zrobi?

php artisan make:model Person -mfs

Wyjaśnienie:

  • Stworzy Model o nazwie Person
  • Stworzy migrację dla tabeli people (liczbę mnogą spokojnie framework ogarnie)
  • stworzy fabrykę PersonFactory
  • stworzy seedera PersonSeeder

I to jest właściwe podejście. Tworzymy model o nazwie, którą jest wielką literą zapisana liczba pojedyncza, resztę tworzymy flagami i Laravel sam dba o konwencje nazewnicze.

Oczywiście możemy utworzyć migrację tak:

php artisan make:migration create_flights_table

Taka komenda utworzy nam tabelę flights, czyli aby teraz dociągnąć model i resztę, musimy nazwać go flight:

php artisan make:model Flight -fsc

Tutaj jeszcze kontroler utworzyłem, bo te flagi są różne, to też warto pamiętać, możemy naprawdę dużo.

Ok, a gdyby nazwa tabeli się jakoś nie zgadzała? Np. model ma nazwę MyFlight, albo tabela ma nazwę „my_flights” a model „Flight”?

Wtedy musimy w modelu określić protected $table = 'my_flights’.

Konwencje nazewnicze dotyczą też tabeli piwotalnych (już o nich mówiliśmy, ale jeszcze raz je przerobimy niedługo). Tam nazwa modelu pierwszego to taka, która zaczyna się wcześniej w alfabecie.

Oto przykład tabeli piwotalnej:

return new class extends Migration
{
    public function up()
    {
        Schema::create('client_flight', function (Blueprint $table) {
            $table->foreignId('client_id');
            $table->foreignId('flight_id');
            $table->primary(['client_id', 'flight_id']);
        });
    }

    //...
}

Jak widać, c jest przed f, dlatego taka nazwa. Inaczej Laravel się nie domyśli czego od niego chcemy.

Mówiliśmy o innych rzeczach, jakich Laravel się domyśla. Ot choćby to, że primary key to int, albo to, że używamy timestamps.

Warto zwrócić uwagę na coś jeszcze, a mianowicie to, że Laravel wnioskuje także po nazwach metod:

class Note extends Model
{
    use HasFactory;
    use SoftDeletes;

    protected $fillable = ['title', 'content'];
    
    public function author(){
            return $this->belongsTo(Person::class, "person_id");
    }
}

Tutaj mamy przykład z naszego projektu, gdzie wszystko jest „cacy”, ale metodę źle nazwaliśmy i jak nie podany „person_id” to Laravel będzie szukał „author_id”, mimo że nazwy tabel, nazwy kolumn z kluczem obcym i modeli się zgadzają.

A tu mamy inny przykład:

class Answer extends Model
{
    use HasFactory;
    protected $fillable = ['name', 'description'];
    public function entry(){
            return $this->belongsTo(GuestEntry::class, 'entry_id');
    }
}

W tym przykładzie nazwa kolumny z kluczem obcym (entry_id) nie idzie w parze z nazwą tabeli modelu-rodzica („guest_entries”).

Gdyby kolumna nazywała się guest_entry_id, to możliwe, że zmiana nazwy metody (Laravel wnioskuje po nazwie metody) z entry na guestEntry zaowocowałaby szukaniem „guest_entry_id”.

Tu natomiast mamy nazwę odpowiadającą nazwie kolumny, ale ta nazwa kolumny nie idzie w parze z nazwą tabeli, która nazywa się „guest_entries”, nie „entries”.

Krótko mówiąc, na tym przykładzie widać, jak wiele popsuć można poprzez zbyt frywolne podchodzenie do dobrych praktyk nazewniczych i jak wyjście z tych problemów może przyprawić o zawrót głowy kogoś, kto mniej rozumie, jak Laravel działa.

Dlatego zawsze przestrzegajmy tych konwencji.