În această mini-serie Nettuts +, vom construi o aplicație web de la zero, în timp ce vom scufunda într-un nou cadru PHP care absoarbe rapid aburi, numit Laravel.
În această lecție, vom lucra pe o parte integrantă a oricărei aplicații web: Modelele. Pe parcurs, vom afla despre implementarea uimitoare a ORM a lui Laravel: Elocvent.
Bine ați venit înapoi la noi Aplicații Web de la Scratch cu Laravel serie! În primul tutorial al seriei, am învățat multe despre Laravel și despre filozofia lui:
Dacă nu ați citit-o încă, ar trebui să aruncați o privire la tutorialul anterior și să o citiți - acest lucru va face mai ușor să înțelegeți filozofia din spatele Laravel și cele mai multe din ceea ce discutăm în acest tutorial.
În această a doua parte a seriei Laravel, vom construi o parte crucială a aplicației noastre de testare web, Instapics, care este implementarea modelului. Fără să mai vorbim, să începem!
Am vorbit deja despre ce modele sunt în unul dintre articolele mele anterioare, Zend Framework from Scratch - Models și Integrating Doctrine ORM, așa că, pentru a evita repetarea, voi scrie esența a ceea ce am scris mai devreme aici. Simțiți-vă liber să vă referiți la celălalt tutorial și să citiți mai multe despre Modelele de acolo.
Rezumat:
Modelele din Laravel, sau în cele mai multe cadre, sunt dezvoltate în același mod. Diferența constă în faptul că Laravel ne oferă o modalitate ușoară de a construi aceste modele, oferindu-ne metode cu scop general pe care majoritatea modelelor le-ar avea nevoie - ORM elocvent.
Un ORM este un mapper obiect-relațional, iar Laravel are unul pe care îl vei iubi absolut! Este numit "Elocvent", deoarece vă permite să lucrați cu obiectele și relațiile bazei de date utilizând o sintaxă elocventă și expresivă.
ORM elocvent este implementarea ORM implementată de Laravel. În opinia mea, este una dintre cele mai bune implementări ORM pe care le-am văzut până acum - rivalizând chiar și pe Doctrine ORM. Este incredibil de elegant, folosind convențiile standard pentru a diminua configurația.
De exemplu, folosind un model Eloquent presupune că tabela reprezentată de model are un id
camp. id
este cheia primară pentru orice înregistrare și este folosită de majoritatea metodelor lui Eloquent.
Un alt lucru pe care Elloquent îl presupune corect este că numele tău de masă este forma plurală a modelului tău. De exemplu, dvs. Utilizator
model va face referire la utilizatori
masa. Deoarece acest lucru nu ar putea fi întotdeauna standard pentru unii, Laravel oferă o modalitate de a trece peste acest lucru: pur și simplu utilizați masă de $
steag:
user clasa se extinde Elocvent public static $ table = 'my_users';
Aceasta va instrui Laravel să nu folosească convenția și să folosească în schimb tabelul specificat.
În cele din urmă, Laravel poate, de asemenea, să automatizeze crearea și actualizarea timbrelor pentru noi. Pentru a face acest lucru, adăugați o creat la
și / sau updated_at
coloana din tabel și setați $ timestamp-ul
pavilion în model:
user class extinde Elocvent public static $ timestamps = true;
Elocvent va vedea steagul și va seta automat creat la
domeniul creării și actualizarea updated_at
câmp de fiecare dată când este actualizată o înregistrare. Destul de cool, huh?
Recuperarea înregistrărilor este o metodă de recuperare a metodei de recuperare a lui Eloquent. De exemplu, trebuie să găsiți o înregistrare specifică a utilizatorului? Doar fa-o:
$ user = Utilizator :: find ($ user_id);
Aceasta returnează a Utilizator
model pe care puteți face operațiuni! Trebuie să utilizați condiționate? Să ne imaginăm că doriți să preluați un utilizator prin adresa de e-mail. Pentru a îndeplini această sarcină, puteți face ceva de genul:
$ user = Utilizator :: unde ('email', '=', $ email) -> first ();
Alternativ, puteți utiliza metodele dinamice ale lui Laravel:
$ user = Utilizator :: where_email ($ email) -> first ();
Introducerea și actualizarea modelelor folosind Eloquent poate fi realizată în trei etape.
$ user = utilizator nou (); // sau a obține un utilizator existent $ user = User :: get ($ user_id);
$ user-> email = '[email protected]'; $ user-> parola = 'test1234';
$ User-> Salvare ();
Elloquent face ca procesul de definire a relațiilor și de recuperare a modelelor aferente să fie simplu și intuitiv.
La naiba! Elocvent susține trei tipuri de relații:
Pentru a defini o relație între modele, va trebui să creați o metodă în ambele modele care "descriu" relațiile dintre ele. De exemplu, să spunem a Utilizator
are unul
user_profile
. Puteți face acest lucru prin definirea unui user_profile
metodă în Utilizator
model:
user class extinde elocvent funcția publică user_profile () return $ this-> has_one ('User_Profile');
pentru că Utilizator
este modelul nostru "dominant" aici (adică un utilizator are un profil și nu un profil are un utilizator), definim că a user_profile
aparține lui
A Utilizator
:
class User_Profile se extinde Elocvent public function user () return $ this-> belongs_to ('User');
Odată ce am definit aceste relații, putem face:
/ * Obțineți obiectul User_Profile al unui utilizator Acest lucru execută două interogări SQL: SELECT * FROM 'utilizatori' WHERE 'id' = $ user_id SELECT * FROM 'user_profiles' WHERE 'user_id' = $ user_id * / $ user = ($ user_id); $ user_profile = $ user-> user_profile; / * Putem de asemenea să o facem și invers. * / $ User_profile = User_Profile :: unde ('user_id', '=', $ user_id) -> first (); $ user = $ user_profile-> utilizator;
Un lucru demn de remarcat aici este o altă convenție: elocvent presupune că cheia străină folosită în user_profile
este numele tabelului referit + _id
. Din nou, dacă doriți să schimbați acest comportament, îl puteți suprascrie:
Utilizatorul de clasă se extinde Elocvent funcția publică user_profile () return $ this-> has_one ('User_Profile', 'user_profile_user_id');
Să spunem că vrem să definim relația dintre a Utilizator
si a lui Fotografie
încărcări. Acesta este un One-to-many relație, spre deosebire de Utilizator
-la-Profilul utilizatorului
relație care a fost Unu la unu. Știm asta Utilizator
are multe
Fotografie
încărcări, astfel:
user-ul de clasă extinde elocvent public funcții photos () return $ this-> has_many ("Photo"); ... class Photo extinde Elocvent public function user () return $ this-> belongs_to ('Utilizator');
Principala diferență aici cu are unul
este că funcția pe care o vom folosi pentru a extrage a Utilizator
fotografiile vor reveni acum mulțime de Fotografie
obiecte. Deci, dacă vrem să aducem toate a Utilizator
fotografiile, am putea face:
$ photos = Utilizator :: găsi ($ user_id) -> photos; foreach ($ fotografii ca $ foto) ...
Nu, referindu-mă la fotografii
ca o proprietate nu este o tipografie. Laravel ne dă un fel de zahăr frumos. De asemenea, am putea face:
$ photos = Utilizator :: găsi ($ user_id) -> photos () -> get ();
Acesta este un pic cam complicat, dar odată implementat, este ușor de manevrat Mulți-to-many relațiile dintre modele. Să ne imaginăm, de exemplu, că, din nou, aveți a Utilizator
model, iar fiecare dintre acești utilizatori poate avea mai multe funcții Grupuri
. A grup
poate avea, de asemenea, mai multe Utilizatori
. Vom folosi trei tabele pentru a reprezenta aceste relații particulare:
Structura de masă convențională elocvent va căuta va fi ceva de genul:
O altă convenție pe care o menționăm aici este aceea că tabela intermediară, GROUP_USER
, este numele singular al celor două tabele pe care le conectează, aranjate în ordine alfabetică cu o subliniere. Ca întotdeauna, suntem liberi să ignorăm acest lucru.
Iată cum codul va arăta în interiorul fiecăruia dintre modelele pentru aceste trei tabele:
() // dacă am fi vrut să suprascriem convenția de numire implicită // pentru tabela intermediară, o putem face așa: // return $ this-> has_many_and_belongs_to ('Group', ' group_listings'); returnați $ this-> has_many_and_belongs_to ('Grup'); ... clasa Group extinde Eloquent public function users () // daca vrem sa suprascriem conventia de numire implicita // pentru tabela intermediara, o putem face asa: // return $ this-> has_many_and_belongs_to ('User ',' group_listings '); returnați $ this-> has_many_and_belongs_to ('Utilizator'); ... clasa Group_User extinde elocvent public function group () return $ this-> has_one ('Group'); funcția publică funcția () return $ this-> has_one ("Utilizator");
Cu acest lucru, putem profita de funcțiile de relație ale lui Eloquent:
// Obțineți grupuri de utilizatori $ groups = User :: find ($ user_id) -> groups; // Obțineți toți utilizatorii dintr-un grup $ users = Group :: find ($ group_id) -> users;
Continuând cu aplicația noastră web, Instapics, Să începem prin crearea bazei de date a aplicației noastre. Pentru a face acest lucru, să notăm funcționalitățile dorite ale aplicației:
Din aceasta putem deduce tabelele bazei de date de care avem nevoie:
Să mergem mai departe și să creăm aceste mese. Pentru acest proiect, voi folosi MySQL; nu ezitați să copiați și să lipiți aceste comenzi.
CREAȚI DATABASE "instapics"; UTILIZAREA "instapicilor"; CREATE TABLE 'instapics'. 'Utilizator' ('id' INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, 'email' VARCHAR (100) NOT NULL, 'password' VARCHAR (100) NOT NULL, 'created_at' DATETIME NOT NULL, 'updated_at' DATETIME NU NULL, KEY PRIMARY ('id'), INDICAT UNIC 'Index_email' ('email')) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE TABLE 'instapics'. 'User_profiles' ('id' INTEGER UNSIGNED NU NULL AUTO_INCREMENT, 'user_id' INTEGER UNSIGNED NOT NULL, 'name' TEXT NOT NULL, 'profile_photo' TEXT NOT NULL, KEY PRIMARY INDEX "Index_user_id" ('user_id'), CONSTRAINT 'FK_user_profiles_user_id' FOREIGN KEY 'FK_user_profiles_user_id' ('user_id') REFERINȚELE utilizatorilor '(' id ') pe DELETE CASCADE LA UPCATE CASCADE) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE TABLE 'instapics'. 'Relații' ('id' INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, 'follower_id' INTEGER UNSIGNED NOT NULL, 'follow_id' INTEGER UNSIGNED NOT NULL, 'created_at' DATETIME NULL, 'updated_at' DATETIME NOT NULL, PRIMARY KEY ('id'), INDICAT UNIQUE 'Index_follower_id_followed_id' ('follower_id', 'followed_id'), CONSTRAINT 'FK_relationships_follower_id' FOREIGN KEY 'FK_relationships_follower_id' ('follower_id') REFERINȚE '' '' '' DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT 'FK_relationships_followed_id' FOREIGN KEY 'FK_relationships_followed_id' ('follow_id') REFERINȚE "utilizatori" ('id') pe DELETE CASCADE PE UPDATE CASCADE) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE TABLE 'instapics'. 'Photos' ('id' INTEGER UNSIGNED NU NULL AUTO_INCREMENT, 'user_id' INTEGER UNSIGNED NOT NULL, 'locație' TEXT NOT NULL, 'description' DATETIME NULL, 'DATETIME NUL NULL, KEY PRIMARY (' id '), CONSTRAINT' FK_photos_user_id 'FOREIGN KEY' FK_photos_user_id '(' user_id ') REFERINȚE' '' '' '' 'DELETE CASCADE ON UPCATE CASCADE' 'ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE TABLE 'instapics'. 'Photo_comments' ('id' INTEGER UNSIGNED NU NULL AUTO_INCREMENT, 'user_id' INTEGER UNSIGNED NOT NULL, 'photo_id' INTEGER UNSIGNED NOT NULL, 'message_TEXT NOT NULL' created_at 'DATETIME NOT NULL' ('id') REFERINȚE 'utilizatori' ('id') pe DELETE CASCADE LA UPCATE CASCADE, CONSTRAINT 'FK_photo_comments_photo_id' KEY FOREIGN (FUNCTIONAL) FK_photo_comments_user_id ' 'FK_photo_comments_photo_id' ('photo_id') REFERINȚELE "fotografii" ('id') pe DELETE CASCADE LA UPCATE CASCADE) MOTOR = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
Alternativ, ați putea folosi migrațiile, dar le vom examina într-o lecție viitoare.
Înainte de a face ceva cu modelele Laravel, trebuie să configurați configurația bazei de date a instalației Laravel. Deschis application / config / database.php, pentru a găsi unele dintre aceste setări:
Adevărat
va loga toate vremurile SQL query în jurnalele Laravel. Lasă asta ca Adevărat
deocamdata.DOP :: FETCH_CLASS
și ar trebui să rămână așa.conexiuni $
array de mai jospgsql
, SQLite
, MySQL
sau sqlsrv
Redis
bibliotecă, puteți configura informațiile despre server aici.În scopul acestui tutorial, vom folosi MySQL. Ta database.php fișier ar trebui să arate ceva de genul acesta (am eliminat comentariile, dar ar trebui să fie bine să păstreze):
retur array ('profile' => true, 'fetch' => PDO :: FETCH_CLASS, 'default' => 'mysql', 'connections' => array ('mysql' ',' username '=>' root ',' password '=>' (yourpassword) ',' charset '=>' utf8 ' prefix '=>', '),' redis '=> array (' default '=> ));
Începeți prin crearea unui model Laravel în interiorul aplicatii / modele pliant. Crea user.php în interiorul și adăugați următorul cod:
Utilizatorul de clasă extinde elocvent
Acum, pe baza analizei noastre asupra a ceea ce Utilizator
relațiile sunt, trebuie să codificăm metodele de relație pentru toate acestea:
user-ul de clasă extinde Eloquent // setarea timestampului $ la true astfel Eloquent // va seta automat valorile create_at // și updated_at static public $ timestamps = true; funcția publică user_profile () return $ this-> has_one ('User_Profile'); următorii funcționari publici () return $ this-> has_many_and_belongs_to ('Utilizator', 'relații', 'follow_id', 'follower_id'); funcție publică după () return $ this-> has_many_and_belongs_to ('Utilizator', 'relații', 'follower_id', 'followed_id'); funcții publice funcții () return $ this-> has_many ("Photo"); funcția publică photo_comment () return $ this-> has_many ('Photo_Comment');
În mod evident, folosim câteva funcții avansate Multe-până-Multe aici, datorită structurii tabelului modelului nostru de adepți (adică utilizatori
tabelul face trimitere la relaţii
tabel care face referire la utilizatori
tabelul din nou). has_many_and_belongs_to
funcția are următoarea semnătură de metodă:
/ ** * Obțineți interogarea pentru o relație multi-multi. * * @parametru parcelar $ model * @param string $ table * @param string $ străin * @param string $ alt * @ relație relație * / funcția publică has_many_and_belongs_to ($ model, $ table = null, $ foreign = null, $ other = null)
Acest lucru ne permite, de fapt, să creăm un model care are o relație Multe-Multe cu ea însăși (adică utilizatorii urmăresc alți utilizatori). Folosim adepți
și ca urmare a
nume de metode pe Utilizator
model pentru a ne permite să obținem următorii utilizatori ai unui utilizator sau să îi primim pe toți utilizatorii pe care le urmărește un singur utilizator.
Urmărind Utilizator
model, creați celelalte modele. Când ați terminat, ar trebui să aveți:
Aceste fișiere vor fi în repozitoriul Git al tutorialului, deci dacă preferați să le descărcați, le puteți găsi aici: https://github.com/nikkobautista/laravel-tutorial
Să începem să folosim modelele noastre prin crearea unor funcții de utilizator pe care le vom avea nevoie în aplicație. Primul pas: înregistrarea utilizatorului. Din tutorialul anterior, am creat deja o Formular de înregistrare / de conectare pe pagina de pornire. Chiar acum, nu face nimic, dar hai să o facem pe a Utilizator
controlor, autentifica
acțiune. Crea application / controllere / user.php cu următorul cod:
class User_Controller extinde Base_Controller funcția publică action_authenticate ()
Deschis cerere / opinii / home / index.blade.php și căutați formularul de autentificare. Actualizați formularul Linia 18 să se prezinte la action_authenticate ()
metodă: