kontakta oss

Det här inlägget postades ursprungligen i juli 2018 av Pedro Rolo och uppdaterades i juni 2020 av Tiago Madeira .
Det finns flera funktioner som gör Ruby on Rails attraktivt, men där det verkligen lyser är när det gäller att få information från relationsdatabaser. Dess ORM -
Aktiv post - erbjuder nu ett mycket moget gränssnitt - att hitta rätt balans mellan kortfatthet och kraft.
I den här artikeln kommer jag att ge några enkla exempel på hur man extraherar information från en databas. Detta är inte tänkt att vara en omfattande guide, utan snarare en uppsättning verktyg som jag har hittat användbara i mitt dagliga arbete. Det jag presenterar nedan är också baserat på den senaste Rails-uppdateringen (Rails 6).
Jag börjar med att definiera en domänmodell mot vilken jag kommer att köra mina frågor:
Vi använder följande domänmodell i våra exempel:

I grund och botten Person och Företag tillhör en Land, och Person och Företag har en många-till-många-relation mellan dem, som lagras i relationstabellen Företagsperson.
Den #activerecord är det som binder modellen i vår ruby-applikation med dess respektive databastabell. Det aktiva postobjektet levereras med en uppsättning metoder som hjälper oss att fråga databasposter så att det inte finns något behov av att använda rå SQL. För jämförelseändamål presenteras översättningen av våra activerecord-frågor till sql-frågor. Du kan enkelt göra denna översättning med #to_sql.
De enklaste frågorna involverar bara en enda tabell och försöker få poster som har vissa specifika värden på sina kolumner.
Låt oss till exempel säga att vi vill hitta vem som har John som förnamn:
Vi kan också använda matriser med önskvärda värden istället för enstaka värden. Det kommer att generera frågor som använder I SQL-nyckelord:
Förutom matriser accepteras även intervall som värdepredikat:
Du kan också ha oändliga intervall:
som nu med Rails 6 helt enkelt kan skrivas så här:
Det är möjligt att begränsa våra frågor till flera samtidiga predikat. Vi kan antingen tillhandahålla #where en hash med flera nyckelord eller så kan vi kedja flera åkallanden av #where:
Om vi annars vill komponera våra predikat med en ELLER Vi kan använda #or.
När vi bara söker efter en specifik rad kan vi använda #find_by istället, som slutar söka när den hittar den första matchningen genom att använda GRÄNS 1
Eller så kan vi tillhandahålla vår egen anpassade gräns genom kedja #limit till vår #where frågor:
Det är möjligt att få rekorden matchar inte ett visst tillstånd genom att använda #not tillsammans med #where:
Det är möjligt att använda #order för att sortera resultaten i stigande eller avtagande ordning:
Det finns flera funktioner som gör det möjligt att fälla ett frågeresultat till vissa värden, till exempel #count, #maximum, #minimum och #average:
Dessutom är det möjligt att gruppera element efter en given kolumn och vika dessa element med dessa vikningsfunktioner och därmed utföra GRUPP_BY frågor:
Det vanligaste användningsfallet för flera tabeller handlar om att ivrigt ladda vissa enheter som är relaterade till vår valda modell, som till exempel kan nås iterativt. Detta problem är allmänt känt som 1 + N frågeproblem och följande interaktion gör det uppenbart:
Som vi ser utförs en ny fråga varje gång vi itererar en person för att komma åt sitt land.
#includes

#includes gör det möjligt för oss att ivrigt ladda all data på en gång och därmed optimera vad som utförs ovan. Det beter sig som en VÄNSTER YTTRE KOPPLINGoch laddar därmed alla poster i den relaterade modellen som berör våra huvudmodellposter.
Men vänta, det är inte en VÄNSTER YTTRE KOPPLING - kan du säga! Tja, eftersom det inte finns några ytterligare begränsningar för de länder vi väljer, föredrar Rails att tillgripa en VAR ID IN fråga, dra nytta av primärnyckelindexet. Men om vi lägger till begränsningar i vår fråga utför aktiv post en VÄNSTER YTTRE KOPPLING istället:
Vad som ska märkas i exemplet ovan är användningen av en hash på whe-villkoret för att specificera begränsningar för våra refererade modeller.
Vi kan också ivrigt ladda flera relationer samtidigt:
Och det är också möjligt att göra det på ett kapslad sätt, genom att skicka en relationshash istället:
#joins

Ibland är vi bara intresserade av de poster som är associerade med den relaterade modulen. När så är fallet använder vi #joins, som har semantiken för en INRE KOPPLING.
Vi illustrerar behovet av denna funktion i följande exempel, där vi bara tänker iterera genom människor som verkligen är associerade med ett land:
Om vi bara är intresserade av poster som är associerade med en relaterad modell med specifika attributvärden kan vi använda #joins och sedan #where för att specificera begränsningar för våra modeller.
Väl, alla frågor som skrivits hittills är ganska långa. När de blir komplicerade eller är avsedda att återanvändas genom vår kod är det bekvämt att ge dem namn.
I äldre versioner av skenor bör du använda ActiveRecord: :Base #scope klassmetod för att skapa sådana återanvändbara frågor. Du kan uppnå samma funktionalitet genom att helt enkelt definiera klassmetoder:
Efter att ha definierat frågorna på ett sådant sätt kan du kedja dessa abstraktioner på hög nivå tillsammans.
Arel är ett domänspecifikt språk som gör det möjligt att uttrycka dina frågor i relationell algebra. I tidigare versioner av Rails var det ganska vanligt att behöva tillgripa Arel för att uppnå några ganska ofta begärda funktioner, men numera täcker Rails 6: s Active Record redan de flesta av dessa användningsfall.
Jag börjar med att presentera några av de redan presenterade Rails 6-frågorna genom att använda Arel istället för vanlig aktiv post. Och senare fokusera på hur man skriver några fall där man fortfarande skulle behöva Arel.
När man skapar Arel-frågor börjar man vanligtvis med att få Arel: :Tabell objekt i SQL-tabellerna vi vill interagera med:
Vi kan komma åt samlingarna på våra bord som en hash. Från dessa tabeller kan man definiera predikat (Arel: :Nod) åberopa metoder på dess attribut, som är tillgängliga genom metoden []:
Predikaten #eq, #not_eq, #lt, #gt, #lteq, #gteq är likvärdiga med operatorerna =,! =, <, >, <=, >= och fungerar så här:
Den #and & #or kan användas för att skapa multitabla predikat och arbeta på ett liknande sätt, så här:
Vi kan senare överföra dessa predikat till #where, och så länge de obligatoriska tabellerna är sammanfogade kommer predikatet att konverteras framgångsrikt till SQL:
Detta är ett användningsfall där man fortfarande behöver tillgripa Arel för att få en databasoberoende fråga. För att göra detta bör man kombinera #matches Arel-predikat med % SQL-jokertecken:
Detta returnerar personer vars efternamn börjar med tecknet ”A”.
Både Arel och Active Record har många fler funktioner än de jag har presenterat här. Men de är mer än tillräckligt för att komma igång med applikationer med enkla krav.
I slutändan kommer det att föredra att välja mellan ActiveRecord-frågemetoder eller Arel, när vi gör våra dagliga frågor. Jag tycker att ActiveRecord-syntaxen är lättare att läsa och använda, men Arel kan fortfarande vara användbar när man hanterar komplexa frågor.


Rails utvecklare med 10+ års erfarenhet av olika tekniker. Jag är intresserad av funktionell programmering.

Datavetenskapsstudent och ImaginaryCloud deltidsarbetare. Ivrig efter att lära sig ny teknik och teknik. Tennis- och pianospelare.
Människor som läste det här inlägget tyckte också att dessa var intressanta: