In deze Nettuts + miniserie bouwen we een geheel nieuwe webtoepassing, terwijl we duiken in een geweldig nieuw PHP-framework dat snel stoom oppikt, genaamd Laravel.
In deze les werken we aan een integraal onderdeel van elke webtoepassing: de modellen. Onderweg komen we te weten over de geweldige ORM-implementatie van Laravel: Welsprekend.
Welkom bij ons Webapplicaties van Scratch met Laravel serie! In de eerste tutorial van de serie hebben we veel geleerd over Laravel en zijn filosofie:
Als je het nog niet hebt gelezen, moet je de vorige zelfstudie bekijken en deze lezen - dit maakt het gemakkelijker om de filosofie achter Laravel te begrijpen en de meeste dingen die we in deze zelfstudie bespreken.
In dit tweede deel van de Laravel-serie zullen we een cruciaal onderdeel van onze testwebtoepassing bouwen, Instapics, wat de Model-implementatie is. Zonder meer, laten we beginnen!
Ik heb al een beetje over wat gesproken modellen zijn in een van mijn vorige artikelen, Zend Framework van Scratch - Models en Integrating Doctrine ORM, dus om mezelf niet te herhalen te herhalen, zal ik de essentie schrijven van wat ik hier eerder heb geschreven. Raadpleeg de andere zelfstudie en lees meer over welke modellen er zijn.
Samenvatting:
Modellen in Laravel, of in de meeste raamwerken, worden op dezelfde manier ontwikkeld. Het verschil is dat Laravel ons een eenvoudige manier geeft om deze modellen te bouwen, door ons algemene methoden te bieden die de meeste modellen nodig hebben: de Weldadige ORM.
Een ORM is een object-relationele mapper en Laravel heeft er een waar je absoluut dol op zal zijn! Het heeft de naam "Eloquent", omdat het u toestaat om met uw databaseobjecten en -relaties te werken met behulp van een welsprekende en expressieve syntaxis.
De Eloquent ORM is de ingebouwde ORM-implementatie van Laravel. Naar mijn mening is het een van de beste ORM-implementaties die ik tot nu toe heb gezien - zelfs in de vorm van Doctrine ORM. Het is ongelooflijk elegant en maakt gebruik van standaardconventies om de configuratie te verminderen.
Als u bijvoorbeeld een Eloquent-model gebruikt, wordt ervan uitgegaan dat de tabel die het model vertegenwoordigt, een ID kaart
veld. De ID kaart
is de primaire sleutel voor elk record en wordt gebruikt door de meeste methoden van Eloquent.
Een ander ding dat Eloyquent terecht veronderstelt, is dat uw tabelnaam de meervoudsvorm van uw model is. Bijvoorbeeld uw Gebruiker
model zal verwijzen naar de gebruikers
tafel. Omdat dit voor sommigen misschien niet altijd de standaard is, biedt Laravel een manier om dit op te heffen: gebruik gewoon de $ table
vlag:
class User breidt Eloquent uit public static $ table = 'my_users';
Dit zal Laravel instrueren om de conventie niet te gebruiken en in plaats daarvan de gespecificeerde tabel te gebruiken.
Ten slotte kan Laravel ook het maken en bijwerken van tijdstempels voor ons automatiseren. Voeg hiervoor een toe gemaakt bij
en / of updated_at
kolom in de tabel en stel de $ timestamp
vlag in het model:
class User breidt Eloquent uit public static $ timestamps = true;
Weldadig ziet de vlag en stelt automatisch de gemaakt bij
veld bij het maken en update het updated_at
veld telkens wanneer een record wordt bijgewerkt. Best cool, he?
Ophalen van records is een fluitje van een cent met de ophaalmethoden van Eloquent. U moet bijvoorbeeld een specifiek gebruikersrecord vinden? Gewoon doen:
$ user = User :: find ($ user_id);
Dit levert a Gebruiker
model waarop je operaties kunt uitvoeren! Moet conditionals worden gebruikt? Laten we ons voorstellen dat u een gebruiker per e-mailadres wilt ophalen. Om deze taak te volbrengen, zou je iets als kunnen doen:
$ user = User :: where ('email', '=', $ email) -> first ();
Als alternatief kunt u de dynamische methoden van Laravel gebruiken:
$ user = User :: where_email ($ email) -> first ();
Het invoegen en bijwerken van modellen met behulp van Eloquent kan in drie stappen worden voltooid.
$ user = new User (); // of krijg een bestaande gebruiker $ user = User :: get ($ user_id);
$ user-> email = '[email protected]'; $ user-> password = 'test1234';
$ Gebruiksvriendelijkheid> save ();
Eloquent maakt het proces van het definiëren van relaties en het ophalen van gerelateerde modellen eenvoudig en intuïtief.
Verdomd goed toch! Eloquent ondersteunt drie soorten relaties:
Om een relatie tussen modellen te definiëren, moet u een methode maken in beide modellen die hun relaties "beschrijven". Laten we bijvoorbeeld zeggen a Gebruiker
heeft een
Gebruikersprofiel
. U kunt dat doen door a te definiëren gebruikersprofiel
methode in de Gebruiker
model:
class User breidt Eloquent uit public function user_profile () return $ this-> has_one ('User_Profile');
Omdat Gebruiker
is ons "dominante" model hier (dat wil zeggen, een gebruiker heeft een profiel en geen profiel heeft een gebruiker), we definiëren dat een Gebruikersprofiel
hoort bij
een Gebruiker
:
class User_Profile breidt Eloquent uit public function user () return $ this-> belong_to ('User');
Zodra we deze relatie hebben gedefinieerd, kunnen we het volgende doen:
/ * Verkrijg het User_Profile-object van een gebruiker Dit voert twee SQL-query's uit: SELECT * FROM 'gebruikers' WHERE 'id' = $ user_id SELECT * FROM 'user_profiles' WHERE 'user_id' = $ user_id * / $ user = User :: find ($ user_id); $ user_profile = $ user-> user_profile; / * We kunnen het ook andersom doen * / $ user_profile = User_Profile :: where ('user_id', '=', $ user_id) -> first (); $ user = $ user_profile-> gebruiker;
Een ding dat het vermelden waard is, is een andere conventie: Eloquent gaat ervan uit dat de externe sleutel is gebruikt in Gebruikersprofiel
is de naam van de tabel waarnaar wordt verwezen + _ID kaart
. Nogmaals, als u dit gedrag wilt wijzigen, kunt u het overschrijven:
class User breidt Eloquent uit public function user_profile () return $ this-> has_one ('User_Profile', 'user_profile_user_id');
Laten we zeggen dat we de relatie tussen een Gebruiker
en zijn Foto
uploads. Dit is een Een te veel relatie, in tegenstelling tot de Gebruiker
-naar-Gebruikersprofiel
relatie die was Een op een. We kennen die Gebruiker
heeft veel
Foto
uploadt, dus:
class User breidt Eloquent uit public function photos () return $ this-> has_many ('Photo'); ... class Photo breidt Eloquent uit public function user () return $ this-> belong_to ('User');
Het belangrijkste verschil hier met heeft een
is dat de functie die we zullen gebruiken om a op te halen Gebruiker
de foto's komen nu terug rangschikking van Foto
voorwerpen. Dus als we alle a wilden ophalen Gebruiker
's foto's, kunnen we doen:
$ photos = User :: find ($ user_id) -> foto's; foreach ($ foto's als $ foto) ...
Nee, verwijzend naar foto's
als een eigenschap is geen typfout. Laravel geeft ons dit leuke stukje suiker. We zouden ook kunnen doen:
$ photos = User :: find ($ user_id) -> photos () -> get ();
Deze is een beetje lastig, maar eenmaal geïmplementeerd, maakt het het gemakkelijk te hanteren Veel te veel relaties tussen modellen. Laten we ons bijvoorbeeld voorstellen dat u, opnieuw, een Gebruiker
model, en elk van deze gebruikers kan meerdere hebben groepen
. EEN Groep
kan ook meerdere hebben gebruikers
. We gebruiken drie tabellen om deze specifieke relaties te representeren:
De conventie waar de tafelstructuur van Eloquent op zal letten, is zoiets als dit:
Een andere conventie die hier op te merken is, is dat de tussentafel, group_user
, zijn de enkelvoudige namen van de twee tabellen die het verbindt, alfabetisch gerangschikt met een onderstrepingsteken. Zoals altijd zijn we vrij om dit te overschrijven.
Hier ziet u hoe de code in elk van de modellen voor deze drie tabellen verschijnt:
class User breidt Eloquent public function groups () // uit als we de standaard benamingconventie // voor de tussentabel willen overschrijven, we kunnen het als volgt doen: // return $ this-> has_many_and_belongs_to ('Group', ' group_listings); return $ this-> has_many_and_belongs_to ('Group'); ... class Group breidt Eloquent uit public function users () // als we de standaardbenamingconventie voor de tussenliggende tabel willen negeren // kunnen we het als volgt doen: // return $ this-> has_many_and_belongs_to ('User ',' group_listings '); return $ this-> has_many_and_belongs_to ('User'); ... class Group_User breidt Eloquent uit public function group () return $ this-> has_one ('Group'); public function user () return $ this-> has_one ('User');
Met dit op zijn plaats, kunnen we dan profiteren van de relatie-functies van Eloquent:
// Krijg de groepen van een gebruiker $ groups = User :: find ($ user_id) -> groups; // Haal alle gebruikers in een groep $ users = Group :: find ($ group_id) -> users;
Verder gaan met onze webapplicatie, Instapics, laten we beginnen met het creëren van de database van onze applicatie. Om dit te doen, laten we de gewenste functionaliteiten van de applicatie noteren:
Hieruit kunnen we de databasetabellen afleiden die we nodig hebben:
Laten we doorgaan en deze tabellen maken. Voor dit project zal ik gebruiken MySQL; voel je vrij om deze commando's te kopiëren en te plakken.
CREATE DATABASE 'instapics'; GEBRUIK 'instapics'; MAAK TAFEL 'instapics'. 'Users' ('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 NOT NULL, PRIMARY KEY ('id'), UNIQUE INDEX 'Index_email' ('email')) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci; MAAK TAFEL 'instapics'. 'User_profiles' ('id' INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, 'user_id' INTEGER UNSIGNED NOT NULL, 'naam' TEXT NOT NULL, 'profile_photo' TEXT NOT NULL, PRIMARY KEY ('id'), UNIEK INDEX 'Index_user_id' ('user_id'), CONSTRAINT 'FK_user_profiles_user_id' FOREIGN KEY 'FK_user_profiles_user_id' ('user_id') REFERENTIES 'gebruikers' ('id') OP VERWIJDEREN CASCADE OP UPDATE CASCADE) MOTOR = InnoDB KARAKTER SET utf8 COLLATE utf8_general_ci; MAAK TAFEL 'instapics'. 'Relaties' ('id' INTEGER NIET GEGEVEN NIET NULL AUTO_INCREMENT, 'follower_id' INTEGER NIET GEGEVEN NIET NULL, 'following_id' INTEGER NIET GEGEVEN NIET NULL, 'created_at' DATETIME NOT NULL, 'updated_at' DATETIME NOT NULL, PRIMARY KEY ('id'), UNIQUE INDEX 'Index_follower_id_followed_id' ('follower_id', 'follows_id'), CONSTRAINT 'FK_relationships_follower_id' FOREIGN KEY 'FK_relationships_follower_id' ('follower_id') REFERENCES 'users' ('id') OP VERWIJDEREN CASCADE OP UPDATE CASCADE, CONSTRAINT 'FK_relationships_followed_id' FOREIGN KEY 'FK_relationships_followed_id' ('follows_id') REFERENTIES 'gebruikers' ('id') OP VERWIJDEREN CASCADE OP UPDATE CASCADE) MOTOR = InnoDB KARAKTER SET utf8 COLLATE utf8_general_ci; MAAK TAFEL 'instapics'. 'Photos' ('id' INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, 'user_id' INTEGER UNSIGNED NOT NULL, 'location' TEXT NOT NULL, 'description' TEXT NOT NULL, 'created_at' DATETIME NOT NULL, 'updated_at 'DATETIME NOT NULL, PRIMARY KEY (' id '), CONSTRAINT' FK_photos_user_id 'FOREIGN KEY' FK_photos_user_id '(' user_id ') REFERENTIES' gebruikers '(' id ') OP VERWIJDEREN CASCADE OP UPDATE CASCADE) MOTOR = InnoDB KARAKTER SET utf8 COLLATE utf8_general_ci; CREËER TAFEL 'instapics'. 'Photo_comments' ('id' INTEGER NIET GEGEVEN NIET NULL AUTO_INCREMENT, 'user_id' INTEGER NIET GEGEVEN NIET NULL, 'photo_id' INTEGER NIET GEGEVEN NIET NULL, 'message' TEXT NOT NULL, 'created_at' DATETIME NOT NULL, ' updated_at 'DATETIME NOT NULL, PRIMARY KEY (' id '), CONSTRAINT' FK_photo_comments_user_id 'FOREIGN KEY' FK_photo_comments_user_id '(' user_id ') REFERENCES' users '(' id ') OP VERWIJDEREN CASCADE OP UPDATE CASCADE, CONSTRAINT' FK_photo_comments_photo_id 'BUITENLANDSE SLEUTEL 'FK_photo_comments_photo_id' ('photo_id') REFERENTIES 'photos' ('id') OP VERWIJDEREN CASCADE OP UPDATE CASCADE) MOTOR = InnoDB KARAKTER SET utf8 COLLATE utf8_general_ci;
Je kunt ook migraties gebruiken, maar we zullen die in een volgende les bespreken.
Voordat we iets doen met Laravel-modellen, moeten we de databaseconfiguratie van onze Laravel-installatie instellen. Open application / config / database.php, om enkele van deze instellingen te vinden:
waar
logt alle SQL-querie-tijden in de Laravel-logboeken. Laat dit zo waar
voor nu.BOB :: FETCH_CLASS
en zou zo moeten worden achtergelaten.$ verbindingen
array net onderpgsql
, sqlite
, mysql
of sqlsrv
Redis
bibliotheek, kunt u hier de serverinformatie instellen.Voor deze tutorial gebruiken we MySQL. Jouw database.php bestand moet er ongeveer zo uitzien (ik heb de opmerkingen verwijderd, maar het zou goed moeten zijn om dit te bewaren):
return array ('profile' => true, 'fetch' => PDO :: FETCH_CLASS, 'default' => 'mysql', 'connections' => array ('mysql' => array ('driver' => 'mysql ',' host '=>' localhost ',' database '=>' instapics ',' gebruikersnaam '=>' root ',' wachtwoord '=>' (yourpassword) ',' charset '=>' utf8 ',' prefix '=> ",),),' redis '=> array (' default '=> array (' host '=>' 127.0.0.1 ',' port '=> 6379,' database '=> 0), ));
Begin met het maken van een Laravel-model in de application / modellen map. creëren user.php binnen en voeg de volgende code toe:
class User breidt Eloquent uit
Nu, op basis van onze beoordeling van wat de Gebruiker
De relaties zijn, we moeten de relatie-methoden coderen voor al deze:
class User breidt Eloquent uit // setting $ timestamp to true, dus Eloquent // zal automatisch de created_at // en updated_at values public static $ timestamps = true instellen; public function user_profile () return $ this-> has_one ('User_Profile'); openbare functie-volgers () return $ this-> has_many_and_belongs_to ('Gebruiker', 'relaties', 'gevolgd_id', 'follower_id'); public function following () return $ this-> has_many_and_belongs_to ('User', 'relationships', 'follower_id', 'follows_id'); openbare functiefoto's () return $ this-> has_many ('Photo'); public function photo_comment () return $ this-> has_many ('Photo_Comment');
Merkbaar maken we hier gebruik van een aantal geavanceerde Many-to-Many-functies, vanwege de tabelstructuur van ons volgermodel (d.w.z. de gebruikers
tabel verwijst naar de relaties
tabel die verwijst naar de gebruikers
tafel opnieuw). De has_many_and_belongs_to
functie heeft de volgende methodehandtekening:
/ ** * Ontvang de vraag voor een veel-op-veel relatie. * * @param string $ model * @param string $ table * @param string $ foreign * @param string $ other * @return Relationship * / public function has_many_and_belongs_to ($ model, $ table = null, $ foreign = null, $ other = null)
Hiermee kunnen we eigenlijk een model maken dat een veel-op-veel-relatie met zichzelf heeft (dat wil zeggen dat gebruikers andere gebruikers volgen). We gebruiken volgelingen
en volgend op
methode namen op de Gebruiker
model om ons in staat te stellen volgers van een gebruiker te krijgen of om alle gebruikers te krijgen die een enkele gebruiker volgt.
Volgens de Gebruiker
model, maak de andere modellen. Als je klaar bent, zou je moeten hebben:
Deze bestanden staan in de Git-repository van de tutorial, dus als je ze liever downloadt, kun je deze hier vinden: https://github.com/nikkobautista/laravel-tutorial
Laten we onze modellen gaan gebruiken door enkele van de gebruikersfuncties te maken die we in de applicatie nodig hebben. Ten eerste: gebruikersregistratie. Van de vorige zelfstudie hebben we al een gemaakt Registratie / aanmeldingsformulier op de startpagina. Op dit moment doet het niets, maar laten we het aansluiten op a Gebruiker
controleur, waarmerken
actie. creëren application / controllers / user.php met de volgende code:
class User_Controller breidt Base_Controller uit public function action_authenticate ()
Open application / views / home / index.blade.php en zoek naar het inlogformulier. Werk het formulier bij Lijn 18 indienen bij de action_authenticate ()
methode: