Kontynuacja kursu Laravela, w którym zboczyliśmy nieco w temat SQL, bo bez dobrej znajomości SQLa trudno jest zrozumieć w pełni to, co robi za nas ORM Laravela.
Ok, rzućmy okiem na ten kod:
CREATE TABLE `contacts` (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
person_id BIGINT UNSIGNED NOT NULL,
city VARCHAR(255) NOT NULL,
street VARCHAR(255) NOT NULL,
PRIMARY KEY(id)
);
Mamy tutaj pierwszy constraint, czyli not null. Jeżeli go mamy, wartość nie może być nullable. Trochę odwrotnie niż w Laravelu, który ten not null dopisuje do każdej kolumny, chyba że określimy inaczej, np. ->nullable().
Ok, default czyli inny constraint:
CREATE TABLE Orders (
ID int NOT NULL,
OrderNumber int NOT NULL,
OrderDate date DEFAULT CURRENT_DATE()
);
W Laravelu jak dodawaliśmy kolumnę do istniejącej tabeli, a ta kolumna nie była ->nullable, to zawsze musieliśmy jej dodać ->default($value).
Ok, unique constraint:
CREATE TABLE Persons (
ID int NOT NULL UNIQUE,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int
);
Swoją drogą tutaj mamy taki kolumnowy constraint (ja go nazywam inline constraint), ale są i tabelkowe:
CREATE TABLE Persons (
ID int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int,
UNIQUE (ID)
);
Działanie jest to samo (choć można podać kilka kolumn tam w nawiasach), po prostu inaczej to wygląda. Constraint może też być nazwany:
CREATE TABLE Persons (
ID int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int,
CONSTRAINT UC_Person UNIQUE (ID,LastName)
);
Jak widać nazwany, tabelkowy nie (jedno)kolumnowy inline, obejmuje kilka kolumn na raz.
Warto pamiętać, że unique constraint aby zadziałał tworzy indeks, zatem aby go usunąć robimy takie coś:
ALTER TABLE Persons
DROP INDEX UC_Person;
Choć w niektórych wersjach SQLa zrobimy to tak:
ALTER TABLE Persons
DROP CONSTRAINT UC_Person;
Dla porównania: dodanie defaulta (który jest constraintem, ale nie tworzy indeksu):
ALTER TABLE Persons
ALTER City SET DEFAULT 'Sandnes';
Już to robiliśmy, podobnie jak dropnięcie defaulta:
ALTER TABLE Persons
ALTER City DROP DEFAULT;
Samo dodanie unique jest bardzo łatwe:
ALTER TABLE Persons
ADD UNIQUE (ID);
Możemy też dodać nazwane:
ALTER TABLE Persons
ADD CONSTRAINT UC_Person UNIQUE (ID,LastName);
Ok, teraz Laravel. Jak dropnąć unique z kolumny:
$table->dropUnique('tablename_column_unique');
A teraz jak sprawić, aby kolumna wcześniej unique przestała nią być:
$table->integer('user_id')->unique(false)->change();
Samo dodanie pola z unique jest bardzo proste:
Schema::table('users', function (Blueprint $table) {
$table->string('email')->unique();
});
W Laravelu domyślnie każda kolumna ma not null. Dodanie kolumny nullable jest proste i intuicyjne:
Schema::table('users', function (Blueprint $table) {
$table->string('email')->nullable();
});
Zmiana (modyfikacja) kolumny z nullable na not null też jest prosta, wykorzystujemy ->change:
$table->string('foo')->nullable(false)->change();
Metodę ->change() możemy używać do modyfikacji innych rzeczy w już istniejących kolumnach:
Schema::table('users', function (Blueprint $table) {
$table->string('name', 50)->change();
});
Oczywiście musimy pamiętać, że jak modyfikujemy to musimy przepisać całość ze zmodyfikowaną zawartością:
Schema::table('users', function (Blueprint $table) {
$table->integer('votes')->unsigned()->default(1)->comment('my comment')->change();
});
Tu nie wiem, co zostało zmodyfikowane, bo nie znam poprzednich migracji (może nazwa, może komentarz, może default). Ale przypomnijmy sobie jak działa modyfikacja w SQL:
ALTER TABLE MyTable
CHANGE COLUMN foo bar VARCHAR(32) NOT NULL FIRST;
Też w sumie nie wiadomo, czy mamy tu tylko rename (z foo na bar) czy varchar zmienił ilość znaków, czy not null poprzednio był a może zmiana to tylko nazwa i first?
Powinniśmy już powoli ogarniać jak to się dzieje i nie dziwić się nazbyt.