Kontakt os

Dette indlæg blev oprindeligt udgivet i juli 2018 af Pedro Rolo og opdateret i juni 2020 af Tiago Madeira .
Der er flere funktioner, der gør Ruby on Rails attraktivt, men hvor det virkelig skinner, er, når det kommer til at få information fra relationelle databaser. Dens ORM -
Aktiv optegnelse - tilbyder nu en meget moden grænseflade - der skaber den rigtige balance mellem kortfattethed og magt.
I denne artikel vil jeg give nogle enkle eksempler på, hvordan man udtrækker information fra en database. Dette er ikke beregnet til at være en omfattende guide, men snarere et sæt værktøjer, som jeg har fundet nyttige i min hverdags arbejde. Det, jeg præsenterer nedenfor, er også baseret på den seneste Rails-opdatering (Rails 6).
Jeg starter med at definere en domænemodel, som jeg vil køre mine forespørgsler mod:
Vi bruger følgende domænemodel i vores eksempler:

Dybest set, Person og Firma tilhører en Land, og Person og Firma har et mange-til-mange-forhold mellem dem, som er gemt i relationstabellen FirmaPerson.
Den #activerecord er det, der binder modellen i vores ruby-applikation med dens respektive databasetabel. Det aktive postobjekt leveres med et sæt metoder, der hjælper os med at forespørge databaseposter, så der er ingen grund til at bruge rå SQL. Til sammenligningsformål præsenteres oversættelsen af vores activerecord-forespørgsler til sql-forespørgsler. Du kan nemt udføre denne oversættelse ved hjælp af #to_sql.
De mest enkle forespørgsler involverer kun en enkelt tabel og forsøger at få de poster, der har bestemte specifikke værdier på deres kolonner.
Lad os for eksempel sige, at vi vil finde ud af, hvem der har John som fornavn:
Vi kan også bruge arrays med ønskelige værdier i stedet for enkeltværdier. Det vil generere forespørgsler, der bruger I SQL-nøgleord:
Ud over arrays accepteres intervaller også som værdiprædikater:
Du kan også have uendelige intervaller:
som nu med Rails 6 simpelthen kan skrives som:
Det er muligt at begrænse vores forespørgsler til flere samtidige prædikater. Vi kan enten levere #where en hash med flere nøgleord, eller vi kan kæde flere påkaldelser af #where:
Hvis vi ellers ønsker at komponere vores prædikater med en ELLER Vi kan bruge #or.
Når vi kun søger efter en bestemt række, kan vi bruge #find_by i stedet, som stopper søgningen, når den finder det første match ved at bruge GRÆNSE 1
Eller vi kan give vores egen brugerdefinerede grænse ved at kæde #limit til vores #where forespørgsler:
Det er muligt at få optegnelserne ikke matchende en bestemt betingelse ved at bruge #not sammen med #where:
Det er muligt at bruge #order for at sortere resultaterne i stigende eller aftagende rækkefølge:
Der er flere funktioner, der gør det muligt at folde et forespørgselsresultat til bestemte værdier, f.eks #count, #maximum, #minimum og #average:
Derudover er det muligt at gruppere elementer efter en given kolonne og folde disse elementer med disse foldefunktioner og dermed udføre GRUPPE_BY forespørgsler:
Den mest almindelige brugssag vedrørende flere tabeller handler om ivrig indlæsning af nogle enheder, der er relateret til vores valgte model, som for eksempel kan åbnes iterativt. Dette problem er almindeligt kendt som 1 + N forespørgsler problem og følgende interaktion gør det tydeligt:
Som vi ser, udføres en ny forespørgsel hver gang vi gentager en person for at få adgang til sit land.
#includes

#includes giver os mulighed for ivrig at indlæse alle data på én gang og dermed optimere det, der udføres ovenfor. Det opfører sig som en VENSTRE YDRE SAMMENFØJNINGog indlæser således alle poster i den relaterede model, der vedrører vores hovedmodelposter.
Men vent, det er ikke en VENSTRE YDRE SAMMENFØJNING - kan du sige! Nå, da der ikke er yderligere begrænsninger for de lande, vi vælger, foretrækker Rails at ty til en HVOR ID IND forespørgsel, der udnytter det primære nøgleindeks. Men hvis vi tilføjer begrænsninger til vores forespørgsel, udfører aktiv post en VENSTRE YDRE SAMMENFØJNING i stedet:
Hvad der skal bemærkes i eksemplet ovenfor er brugen af en hash på whe-betingelsen for at specificere begrænsninger på vores refererede modeller.
Vi kan også ivrige indlæse flere relationer på én gang:
Og det er også muligt at gøre det på en indlejret måde ved at videregive en relations-hash i stedet:
#joins

Nogle gange er vi kun interesserede i de poster, der er knyttet til det relaterede modul. Når dette er tilfældet, bruger vi #joins, som har semantikken af en INDRE SAMMENFØJNING.
Vi illustrerer behovet for denne funktion i følgende eksempel, hvor vi kun agter at gentage gennem mennesker, der faktisk er forbundet med et land:
Hvis vi kun er interesseret i poster, der er knyttet til en relateret model med specifikke attributværdier, kan vi bruge #joins og derefter #where for at specificere begrænsninger på vores modeller.
Godt, alle forespørgsler skrevet indtil videre er ret lange. Når de bliver komplicerede eller er beregnet til at blive genbrugt gennem vores kode, er det praktisk at give dem navne.
I ældre versioner af skinner skal du bruge ActiveRecord: :Base #scope klassemetode til at oprette sådanne genanvendelige forespørgsler. Du er i stand til at opnå den samme funktionalitet ved blot at definere klassemetoder:
Når du har defineret forespørgslerne på en sådan måde, er du i stand til at kæde disse abstraktioner på højt niveau sammen.
Arel er et domænespecifikt sprog, der giver mulighed for at udtrykke dine forespørgsler i relationel algebra. I tidligere versioner af Rails var det ret almindeligt at skulle ty til Arel for at udføre nogle ret ofte efterspurgte funktionaliteter, skønt i dag dækker Rails 6s Active Record allerede de fleste af disse brugssager.
Jeg vil starte med at præsentere nogle af de allerede præsenterede Rails 6 forespørgsler ved at bruge Arel i stedet for almindelig aktiv post. Og senere fokusere på, hvordan man skriver nogle sager, hvor man stadig ville have brug for Arel.
Når man opretter Arel-forespørgsler starter man normalt med at få Arel: :Tabel objekter i SQL-tabellerne, vi vil interagere med:
Vi kan få adgang til samlingerne på vores tabeller som en hash. Fra disse tabeller er man i stand til at definere prædikater (Arel: :Knudepunkt) påberåbe sig metoder på dens attributter, som er tilgængelige via metoden []:
Prædikaterne #eq, #not_eq, #lt, #gt, #lteq, #gteq svarer til operatørerne =,! =, <, >, <=, >= og fungerer sådan:
Den #and & #or kan bruges til at oprette multitable prædikater og arbejde på en lignende måde, som denne:
Vi kan senere videregive disse prædikater til #where, og så længe de krævede tabeller er forbundet, konverteres prædikatet med succes til SQL:
Dette er et brugssager, hvor man stadig skal ty til Arel for at få en databaseuafhængig forespørgsel. For at gøre det skal man kombinere #matches Arel-prædikat med % SQL-jokertegn:
Dette returnerer personer, hvis efternavn starter med tegnet „A“.
Både Arel og Active Record har mange flere funktionaliteter end dem, jeg her har præsenteret. Men de er mere end nok til at komme i gang med applikationer med enkle krav.
I sidste ende kommer det til præference at vælge mellem ActiveRecord-forespørgselsmetoder eller Arel, når vi udfører vores daglige forespørgsler. Jeg finder ActiveRecord-syntaksen lettere at læse og bruge, men Arel kan stadig være nyttig, når man beskæftiger sig med komplekse forespørgsler.


Rails-udvikler med 10+ års erfaring med forskellige teknologier. Jeg er interesseret i funktionel programmering.

Datalogstuderende og ImaginaryCloud deltidstimer. Ivrig efter at lære nye teknologier og teknikker. Tennis og klaverspiller.
People who read this post, also found these interesting: