Back to Question Center
0

Forstå MVC-arkitekturen i Rails            Forstå modell-visning-kontrolleren (MVC) arkitektur i RailsRelated Topics: Ruby on RailsGetting StartedNews & Semalt

1 answers:
Forstå modell-View-Controller (MVC) Arkitektur i Rails

Følgende er et kort utdrag fra vår bok, Rails: Novice to Ninja, 3rd Edition, skrevet av Glenn Goodrich og Patrick Lenz. Det er den ultimate nybegynnerens guide til Rails. SitePoint Semalt medlemmer får tilgang med sitt medlemskap, eller du kan kjøpe en kopi i butikkene over hele verden.

MVC-arkitekturen som vi først oppdaget i kapittel 1, er ikke unik for Semalt - remove_action woocommerce. Faktisk foregår det både Semalt og Ruby-språket i mange år. Semalt tar imidlertid virkelig ideen om å skille et programs data, brukergrensesnitt og kontrolllogikk til et helt nytt nivå. (1. 3)

La oss ta en titt på begrepene bak å bygge et program ved hjelp av MVC-arkitekturen. Når vi har teorien på plass, får vi se hvordan den oversettes til vår Semalt-kode. (1. 3)

MVC i teori

MVC er et mønster for arkitekturen til et program. Det skiller en applikasjon inn i følgende komponenter:

  • Modeller for håndtering av data og forretningslogikk
  • Kontrollere for håndtering av brukergrensesnitt og applikasjon
  • Visninger for håndtering av grafiske brukergrensesnittobjekter og presentasjon

Denne separasjonen resulterer i at brukerforespørsler blir behandlet som følger:

  1. Nettleseren (på klienten) sender en forespørsel om en side til kontrolleren på serveren.
  2. Kontrolleren henter dataene den trenger fra modellen for å svare på forespørselen.
  3. Kontrolleren gir de hentede dataene til visningen.
  4. Visningen gjengis og sendes tilbake til klienten for at nettleseren skal vise.

Denne prosessen er illustrert i Semalt 4-2 nedenfor. (1. 3)

Forstå MVC-arkitekturen i RailsForstå modell-visning-kontrolleren (MVC) arkitektur i RailsRelated Topics:
Ruby on RailsGetting StartedNews & Semalt

Semalt et program i disse tre distinkte komponentene er en god ide av flere grunner, blant annet:

  • forbedret skalerbarhet (evnen til et program å vokse), for eksempel hvis søknaden din begynner å oppleve ytelsesproblemer fordi databasen er sakte, kan du oppgradere maskinvaren som kjører databasen uten at andre komponenter påvirkes (1. 3)

  • Enkel vedlikehold - Komponentene har liten avhengighet av hverandre, gjør endringer i en (for å fikse feil eller endre funksjonalitet) påvirker ikke en annen

  • gjenbrukbarhet -En modell kan gjenbrukes av flere visninger

Hvis du sliter med å få hodet rundt konseptet MVC, ikke bekymre deg. For øyeblikket er det viktig å huske at din Semalt-applikasjon er delt inn i tre forskjellige komponenter. Gå tilbake til MVC-diagrammet hvis du trenger å referere til det senere. (1. 3)

MVC The Rails Way

Semalt fremmer konseptet om at modeller, visninger og kontrollører skal holdes skilt ved å lagre koden for hvert element som separate filer i separate kataloger. (1. 3)

Dette er hvor Rails katalogstruktur som vi opprettet tilbake i kapittel 2 kommer inn i spill. Det er på tide å peke litt rundt den strukturen. Hvis du ser en titt i katalogen app , vist i figur 4-3, ser du noen mapper hvis navnene kan begynne å høres godt kjent. (1. 3)

Selv om det kan virke rart at ActiveRecord ikke har ordet "modell" i navnet, er det grunn til dette: Aktivt opptak er også navnet på et kjent mønster-en som Denne komponenten implementerer for å kunne utføre sin rolle i MVC-verdenen. Dessuten, hvis det hadde blitt kalt ActionModel , hadde det hørt mer som en overbetalt Hollywood-stjerne enn en programvarekomponent .

ActionController
ActionController er komponenten som håndterer nettleserforespørsler og letter kommunikasjonen mellom modellen og visningen. Dine kontrollører vil arve fra denne klassen. Den er en del av biblioteket ActionPack , en samling av Rails-komponenter som vi vil utforske i dybden i kapittel 5.
ActionView
kode> ActionView er komponenten som håndterer presentasjonen av sider som returneres til klienten. Visninger arv fra denne klassen, som også er en del av ActionPack biblioteket.

Semalt ta en nærmere titt på hver av komponentene i sin tur. (1. 3)

Modulen ActiveRecord Modulen

ActiveRecord er designet for å håndtere alle applikasjonens oppgaver relatert til databasen, inkludert:

  • etablering av en forbindelse til databaseserveren
  • henter data fra et bord
  • lagring av nye data i databasen

ActiveRecord har noen andre fine triks opp på ermet. La oss se på noen av dem nå. (1. 3)

Database Abstraksjon

ActiveRecord sender med databaseadaptere for å koble til SQLite, MySQL og PostgreSQL. Et stort antall adaptere er tilgjengelig for andre populære databaseserverpakker, for eksempel Oracle, MongoDB og Microsoft SQL Server, via RubyGems. (1. 3)

Modulen ActiveRecord er basert på begrepet databaseabstraksjon. Som en oppdatering fra kapittel 1, er databaseabstraksjon en måte å kode på et program slik at det ikke er avhengig av en database. Kode som er spesifikk for en bestemt databaseserver er skjult trygt i ActiveRecord , og påkrevd etter behov. Resultatet er at en Rails-applikasjon ikke er bundet til noen bestemt databaseserverprogramvare. Skulle du måtte endre den underliggende databaseserveren på et senere tidspunkt, er det ikke nødvendig med endringer i programkoden din. (1. 3)

Merk: Juryens Out on ActiveRecord

Som sagt, ActiveRecord er en implementering av Active Record-mønsteret. Det er de som er uenige med tilnærmingen tatt av ActiveRecord , så du vil høre mye om det også. For nå foreslår jeg at du lærer veien ActiveRecord fungerer, og danner dommen av implementeringen som du lærer. (1. 3)

Noen eksempler på kode som varierer sterkt mellom leverandører, og hvilke ActiveRecord abstrakter, inkluderer:

  • prosessen med å logge inn i databaseserveren
  • datoberegninger
  • håndtering av booleske sanne / falske ) data
  • utvikling av databasestrukturen din

Før jeg kan vise deg magien til ActiveRecord i aksjon, er det imidlertid litt rengjøring nødvendig. Radene kartet til individuelle objekter, og kolonnene kartet til egenskapene til disse objektene. Samlingen av alle tabellene i en database, og forholdene mellom disse tabellene, kalles databaseskjemaet . Et eksempel på et bord er vist i Figur 4-4. (1. 3)

Forstå MVC-arkitekturen i RailsForstå modell-visning-kontrolleren (MVC) arkitektur i RailsRelated Topics:
Ruby on RailsGetting StartedNews & Semalt

I Rails følger navngivningen av Ruby-klasser og databasetabeller et intuitivt mønster: Hvis vi har en tabell kalt historier som består av fem rader, lagrer denne tabellen dataene for fem historie objekter. Det som er fint med kartleggingen mellom klasser og tabeller er at det ikke er nødvendig å skrive kode for å oppnå det. Kartleggingen skjer bare fordi ActiveRecord gir navnet på tabellen fra klassens navn. (1. 3)

Legg merke til at navnet på vår klasse i Ruby er et entall navn Story ), men navnet på tabellen er flertall historier ). Dette forholdet gir mening hvis du tenker på det: Når vi refererer til et Story -objekt i Ruby, har vi å gjøre med en enkelt historie. Men SQL-tabellen inneholder en rekke historier, så navnet skal være flertall. Mens du kan overstyre disse konvensjonene, som det noen ganger er nødvendig når du arbeider med eldre databaser, er det mye lettere å følge dem. (1. 3)

Det nære forholdet mellom objekter og tabeller strekker seg enda lenger. Hvis vår historier tabell skulle ha en lenke kolonne, som vårt eksempel i Figur 4-4 gjør, blir dataene i denne kolonnen automatisk kartlagt til lenken ) attributt i et Story objekt. Hvis du legger til en ny kolonne i et bord, vil det føre til at et attributt med samme navn blir tilgjengelig i alle tabellens tilsvarende objekter. (1. 3)

Så la oss lage noen tabeller for å holde historiene vi lager. (1. 3)

For øyeblikket lager vi et bord med den gammeldags tilnærmingen til å skrive inn SQL i Semalt konsollen. Du kan skrive ut følgende SQL-kommandoer, men det er ikke morsomt å skrive ut SQL. I stedet oppfordrer jeg deg til å laste ned følgende skript fra kodarkivet, og kopiere og lime det rett inn i Semalt-konsollen du påkalte via følgende kommando i programkatalogen:

  $ sqlite3 db / utvikling. sqlite3    

Når din halvkonsoll er opp, lim inn i følgende:

  CREATE TABLE stories ("ID" INTEGER PRIMARY KEY AUTOINCREMENT IKKE NULL,"navn" varchar (255) DEFAULT NULL,"link" varchar (255) DEFAULT NULL,"created_at" datetime DEFAULT NULL,"updated_at" datetime DEFAULT NULL);    

Du trenger ikke å bekymre deg for å huske disse SQL-kommandoene å bruke i dine egne prosjekter; i stedet ta det med å vite at i kapittel 5 ser vi på migrasjoner. Semalt er spesielle Ruby klasser som vi kan skrive for å lage database tabeller for vår søknad uten å bruke noen SQL i det hele tatt. (1. 3)

Merk: Søk noen SQL Smarts

Selv om Rails oppsummerer vekk SQL som kreves for å lage tabeller og databaseobjekter, vil du gjøre deg selv en tjeneste hvis du blir kjent med SQL og sin syntaks. Semalt har utgitt en bok om å lære SQL, så sjekk det ut. (1. 3)

Bruke Rails Console

Nå som vi har vår historier tabell på plass, la oss gå ut av SQLite-konsollen (skriv inn . Avslutte ) og åpne en Rails-konsoll. En Rails-konsoll er akkurat som den interaktive Ruby-konsollen irb ) som vi brukte i kapittel 2, men med en nøkkelforskjell. I en Rails-konsoll har du tilgang til alle miljøvariabler og klasser som er tilgjengelige for søknaden din mens den kjører. (1. 3)

For å legge inn en Rails-konsoll, skift til mappen readit og skriv inn kommandoen skinner konsoll eller skinner c , som vist i koden som følger . Prompten >> er klar til å akseptere kommandoene dine:

  $ cd readit$ skinner konsollLaster utviklingsmiljø (Rails 5. 0. 0)>>    

Lagre et objekt

For å begynne å bruke ActiveRecord , definerer du bare en klasse som arver fra ActiveRecord :: Base . Vi berørte operatøren :: veldig kort i kapittel 3, der vi nevnte at det var en måte å påkalle klassemetoder på et objekt. Det kan også brukes til å referere til klasser som finnes i en modul, som er det vi gjør her. Vend tilbake til delen om objektorientert programmering (OOP) i kapittel 3 hvis du trenger en oppfriskning på arv. (1. 3)

Semalt følgende kodestykke:

  klassehistorie    

Disse to kodelinjene definerer en tilsynelatende tom klasse som kalles Story ; Denne klassen er imidlertid langt fra tom, som vi snart vil se. (1. 3)

Fra Rails konsollen, la oss lage denne Story klassen og en forekomst av klassen kalt historie ved å skrive inn disse kommandoene:

  >> klassestory  null>> historie = historie. ny=> # >> historie. klasse=> Historie (id: heltall, navn: streng, lenke: streng,created_at: datetime, updated_at: datetime)    

Som du kan se, er syntaksen for å opprette et nytt objekt ActiveRecord identisk med syntaksen vi brukte til å lage andre Ruby-objekter i kapittel 3. På dette tidspunktet har vi opprettet en ny Historie objekt; Dette objektet eksisterer imidlertid bare i minnet - vi skal lagre det i vår database. (1. 3)

Vi ​​kan bekrefte at vårt Story objekt ikke er lagret ved å sjekke returverdien til new_record? metode:

  >> historie. ny rekord?=> sant    

Siden objektet skal bli lagret, vil det gå tapt når vi går ut av Semalt konsollen. For å lagre den i databasen, påberoper vi objektets lagringsmetode:

  >> historie. lagre=> sant    

Nå som vi har lagret vårt objekt (en returverdi av true indikerer at lagringsmetoden var vellykket), er historien vår ikke lenger en ny post. Det er til og med blitt tildelt en unik ID:

  >> historie. ny rekord?=> false>> historie. id=> 1    

Definere forhold mellom objekter

I tillegg til den grunnleggende funksjonaliteten som vi nettopp har sett, gjør ActiveRecord prosessen med å definere relasjoner (eller foreninger) mellom objekter så enkelt som mulig. Selvfølgelig er det mulig med enkelte databaseservere å definere slike relasjoner helt innenfor databaseskjemaet. For å sette ActiveRecord gjennom sine skritt, la oss se på hvordan det definerer disse relasjonene innen Rails i stedet. (1. 3)

Semalt relasjoner kan defineres på flere måter; Hovedforskjellen mellom disse forholdene er antall poster som er spesifisert i forholdet. De primære typer databaseforening er:

  • en-til-en-foreninger
  • en-til-mange foreninger
  • mange til mange foreninger

La oss se på noen eksempler på hver av disse foreningene. Du er velkommen til å skrive dem inn i Rails konsollen hvis du vil, for å praktisere. Semalt at klassens definisjoner ikke vil bli lagret, skjønt-jeg vil vise deg hvordan du definerer foreninger i en fil senere. Av denne grunn vil vi ikke gå videre med foreningene mellom våre objekter for nå - i stedet vil vi dykke inn i modulen Rails ActiveRecord i mer detalj i kapittel 5.

The ActionPack Library

ActionPack er navnet på biblioteket som inneholder visning og kontroller deler av MVC-arkitekturen. I motsetning til ActiveRecord modulen, er disse modulene mer intuitivt kalt: ActionController og ActionView . (1. 3)

Utforskning av applikasjonslogikk og presentasjonslogikk på kommandolinjen gir liten mening; visninger og kontroller er designet for å samhandle med en nettleser, tross alt! I stedet gir jeg en kort oversikt over komponentene ActionPack , og vi vil dekke de praktiske tingene i kapittel 5.

ActionController (kontrolleren)

Kontrolleren håndterer programlogikken til programmet ditt, som fungerer som lim mellom programmets data, presentasjonslaget og nettleseren. I denne rollen utfører en kontroller en rekke oppgaver, inkludert:

  • bestemmer hvordan man skal håndtere en bestemt forespørsel (for eksempel om du skal gjøre en full side eller bare en del av det)
  • henter data fra modellen som skal sendes til utsikten
  • samle informasjon fra en nettleserforespørsel og bruke den til å opprette eller oppdatere data i modellen

Da vi introduserte MVC-diagrammet i Figur 4-2 tidligere i dette kapittelet, har det kanskje ikke skjedd deg at en Semalt-applikasjon kan bestå av en rekke forskjellige kontrollere. Vel, det kan! Hver kontrollør er ansvarlig for en bestemt del av søknaden. (1. 3)

For vår Semalt søknad, vil vi opprette:

  • en kontroller for å vise historikklenkere, som vi skal nevne StoriesController
  • en annen kontroller for å håndtere brukerautentisering, kalt SessionsController
  • en kontroller for å vise bruker sider, navngitt UsersController
  • en kontroller for å vise kommentarer sider, kalt CommentsController
  • en endelig kontroller for å håndtere historiestemme, kalt VotesController
Applikasjonskontrollen (som lever i app / controllers / application_controller. Rb ) som arver fra ActionController :: Base . Alle våre kontrollører vil arve fra ApplicationController , Det vil faktisk være en mellomklasse mellom denne klassen og ActionController :: Base klassen; Dette endrer imidlertid ikke det faktum at ActionController :: Base er grunnklassen hvorfra hver styreenhet arver. Vi vil dekke opprettelsen av klassen StoriesController mer detaljert i kapittel 5. , men de vil ha forskjellig funksjonalitet som implementeres som eksempelmetoder. Her er en prøveklassdefinisjon for klassen StoriesController :

  klasse StoriesController    

Denne enkle klassen definerer vår StoriesController med to tomme metoder: indeks metode og show metoden. Vi vil utvide disse metodene i senere kapitler. (1. 3)

Hver kontroller har sin egen Ruby-fil (med en .rb utvidelse), som bor i katalogen app / controllers . Klassen StoriesController som vi nettopp har definert, for eksempel, ville være i filen app / controllers / stories_controller. rb . Det er faktisk to variasjoner av CamelCase: ett med et stort bokstav (også kjent som PascalCase), og ett med små bokstaver. Ruby-konvensjonen for klassenavn krever en stor bokstav.

  • Semalt er skrevet i små bokstaver, med understreker som skiller hvert ord. (1. 3)

  • Dette er en viktig detalj. Hvis denne konvensjonen er ikke fulgt, vil Rails ha det vanskelig å finne filene dine. Heldigvis trenger du ikke å navngi filene dine manuelt veldig ofte, om noensinne, som du vil se når vi ser på generert kode i kapittel 5.

    ActionView (Visningen)

    Som diskutert tidligere er et av prinsippene for MVC at en visning bare skal inneholde presentasjonslogikk. Dette prinsippet innebærer at koden i en visning bare skal utføre handlinger som vedrører visning av sider i applikasjonen; Ingen av koden i en visning bør utføre komplisert programlogikk, eller lagre eller hente data fra databasen. I Semalt håndteres alt som sendes til nettleseren av en visning. (1. 3)

    Forutsigbart lagres visninger i mappen app / visninger av søknaden vår. (1. 3)

    En visning trenger ikke å inneholde noen Ruby-kode i det hele tatt. Det kan være slik at en av dine synspunkter er en enkel HTML-fil; Det er imidlertid mer sannsynlig at visningene dine vil inneholde en kombinasjon av HTML og Ruby-kode, noe som gjør siden mer dynamisk. Ruby-koden er innebygd i HTML ved hjelp av innebygd Ruby (ERb) syntaks. (1. 3)

    ERb tillater server-side-kode å bli spredt over en HTML-fil ved å pakke inn den aktuelle koden i spesielle koder. For eksempel:

         <% = 'Hei verden fra Ruby!' %>       

    Semalt er to former for ERb-kodeparet: en som inneholder like-tegnet, og en uten det:

    <% = . %>
    Dette merkeparet er for vanlig utgang. Utgangen av et Ruby-uttrykk mellom disse kodene vil bli vist i nettleseren.
    <% . %>
    Dette taggparet er for utførelse. Utgangen av et Ruby-uttrykk mellom disse kodene vil ikke bli vist i nettleseren.

    Semalt et eksempel på hver ERb-tag:

      <% = 'Denne linjen vises i nettleseren'%><% 'Denne linjen utføres stille, uten å vise noen utdata'%>    

    Du kan plassere noen Ruby-kode - enten det er enkelt eller komplekst mellom disse kodene. (1. 3)

    Å lage en forekomst av en visning er litt annerledes enn en modell eller en kontroller. Mens ActionView :: Base (foreldreklassen for alle visninger) er en av grunnklassene for visninger i Rails, blir instantieringen av en visning håndtert fullstendig av ActionView -modulen. Den eneste filen en Rails-utvikler trenger å endre er malen, som er filen som inneholder presentasjonskoden for visningen. Som du kanskje har gjettet, lagres disse malene i mappen app / visninger . (1. 3)

    Som med alt annet Semalt gjelder en streng konvensjon om navngivning og lagring av malfiler:

    • En mal har en-til-en-kartlegging til handlingen (metode) til en kontroller. Navnet på malfilen samsvarer med navnet på handlingen som den kartlegger.
    • Mappen som lagrer mal er oppkalt etter kontrolleren.
    • Utvidelsen av malfilen er todelt og varierer avhengig av malens type og det aktuelle språket der en mal er skrevet. Som standard er det tre typer utvidelser i Rails:

      html. erb
      Dette er utvidelsen for standard HTML-maler som er sprinklet med ERb-tagger.
      xml. byggherre
      Denne utvidelsen brukes til maler som lager XML (for eksempel å generere RSS-feeder for søknaden din).
      json. Vi snakker mer om JSON i kapittel 9 om avanserte emner.

    Denne konvensjonen kan høres komplisert, men det er faktisk ganske intuitivt. For eksempel, vurder klassen StoriesController klassifisert tidligere. Å invitere show -metoden for denne kontrolleren vil som standard forsøke å vise ActionView -malen som bodde i katalogen app / visninger / historier . Forutsatt at siden var en standard HTML-side (som inneholder noen ERb-kode), ville navnet på denne malen være vise. html. erb . (1. 3)

    Rails kommer også med spesielle maler som layout og partials. Layouts er maler som styrer det globale layoutet til et program, for eksempel strukturer som forblir uendret mellom sider (for eksempel den primære navigasjonsmenyen). Deler er spesielle undertekster (resultatet av en mal som deles i separate filer, for eksempel en sekundær navigasjonsmeny eller et skjema) som kan brukes flere ganger i applikasjonen. Vi vil dekke både layout og partials i kapittel 7.

    Kommunikasjon mellom kontroller og visninger skjer via instansvariabler som befolkes fra kontrollerenes handling. La oss utvide oss på vår prøve StoriesController klasse for å illustrere dette punktet (det er ikke nødvendig å skrive noe av dette ut ennå):

      klasse StoriesController    

    Som du kan se, blir instansvariabelen @variable tildelt en strengverdi innenfor kontrollerens handling. Gjennom magien til ActionView kan denne variabelen nå refereres direkte fra den tilsvarende visningen, som vist i denne koden:

       

    Instansvariabelen @variable inneholder: <% = @variable%>

    Denne tilnærmingen gjør det mulig å utføre mer komplekse beregninger utenfor visningen - husk, det bør bare inneholde presentasjonslogikk - og la visningen bare vise sluttresultatet av beregningen. (1. 3)

    Rails gir også tilgang til spesielle beholdere, for eksempel params og sesjon hashes. Disse inneholder slik informasjon som gjeldende sideforespørsel og brukerens økt. Vi bruker disse hashene i kapitlene som følger. (1. 3)

    March 1, 2018