Ruby on Rails ('Rails') on suosittu avoimen lähdekoodin kehys, joka perustuu Rubiini ohjelmointikieli, joka pyrkii yksinkertaistamaan ja virtaviivaistamaan verkkosovellusten kehittämisprosessia.
Kiskot on rakennettu kokoonpano . Yksinkertaisesti sanottuna tämä tarkoittaa, että oletuksena Rails olettaa sen olevan asiantuntijakehittäjät noudattaa 'tavanomaisia' parhaiden käytäntöjen käytäntöjä (esimerkiksi nimeäminen, koodirakenne ja niin edelleen), ja jos teet niin, asiat toimivat sinulle 'automaattisesti' ilman, että sinun tarvitsee määrittää näitä yksityiskohtia. Vaikka tällä paradigmalla on etunsa, se ei myöskään ole ilman sudenkuoppia. Erityisesti 'taika', joka tapahtuu kulissien takana puitteissa, voi joskus johtaa päähän, sekaannukseen ja 'mitä hittoa tapahtuu?' erityyppisiä ongelmia. Sillä voi olla myös ei-toivottuja seurauksia turvallisuuden ja suorituskyvyn suhteen.
Vaikka Rails onkin helppokäyttöinen, sitä ei myöskään ole vaikea käyttää väärin. Tässä opetusohjelmassa tarkastellaan 10 yleistä Rails-ongelmaa, mukaan lukien niiden välttäminen ja niiden aiheuttamat ongelmat.
Rails perustuu MVC-arkkitehtuuri . Rails-yhteisössä olemme puhuneet siitä rasvamalli, laiha ohjain jonkin aikaa, mutta useat viimeisimmät perimäni Rails-sovellukset ovat rikkoneet tätä periaatetta. Näkymälogiikan (joka on paremmin sijoitettu auttajaan) tai toimialue- / mallilogiikan siirtäminen ohjaimeen on aivan liian helppoa.
Ongelmana on, että ohjainobjekti alkaa rikkoa yhden vastuun periaate koodikannan tulevaisuuden muutosten tekeminen vaikeaksi ja alttiiksi virheille. Yleensä vain ohjaimessa tarvitsemasi logiikkatyypit ovat:
Vaikka tämä ylittää edelleen yhden vastuun periaatteen rajat, se on eräänlainen vähimmäisvaatimus, jonka Rails-kehys edellyttää meiltä ohjaimessa.
Rails-mallinnuslaite, ERB , on loistava tapa rakentaa vaihtelevaa sisältöä sisältäviä sivuja. Jos et ole varovainen, voit pian saada suuren tiedoston, joka on sekoitus HTML- ja Ruby-koodia ja jota voi olla vaikea hallita ja ylläpitää. Tämä on myös alue, joka voi johtaa toistamiseen, mikä johtaa rikkomuksiin KUIVA (älä toista itseäsi) periaatteita.
Tämä voi ilmetä monin tavoin. Yksi on ehdollisen logiikan liikakäyttö näkymissä. Tarkastellaan yksinkertaisena esimerkkinä tapausta, jossa meillä on current_user
käytettävissä oleva menetelmä, joka palauttaa kirjautuneen käyttäjän. Usein näkemystiedostoissa on tällaisia ehdollisia logiikkarakenteita:
Welcome, Guest
Parempi tapa käsitellä jotain tällaista on varmistaa, että current_user
palauttaa objektin On aina set, onko joku kirjautunut sisään vai ei, ja että se vastaa näkymässä käytettyihin menetelmiin kohtuullisella tavalla (joskus kutsutaan nollakohteeksi). Voit esimerkiksi määrittää current_user
auttaja sisään app/controllers/application_controller
kuten tämä:
require 'ostruct' helper_method :current_user def current_user @current_user ||= User.find session[:user_id] if session[:user_id] if @current_user @current_user else OpenStruct.new(name: 'Guest') end end
Tämän avulla voit korvata edellisen näkymäkoodiesimerkin tällä yksinkertaisella koodirivillä:
Welcome,
Pari suositeltavaa Rails-suositusta:
Koska logiikan minimoimiseksi näkymissä ja ohjaimissa on annettu ohjeita, ainoa paikka, joka on jäljellä MVC-arkkitehtuuri laittaa kaikki tämä logiikka olisi malleissa, eikö?
No, ei aivan.
Monet Rails-kehittäjät todella tekevät tämän virheen ja lopulta tarttuu kaikkeen ActiveRecord
malliluokat, jotka johtavat mongotiedostoihin, jotka paitsi rikkovat yhden vastuun periaatetta, mutta ovat myös ylläpitopainoja.
Toiminnallisuudella, kuten sähköposti-ilmoitusten luominen, käyttöliittymä ulkoisiin palveluihin, muuntaminen muihin tietomuotoihin ja vastaavilla, ei ole paljon tekemistä ActiveRecord
mallin, jonka pitäisi tehdä vähän enemmän kuin löytää ja säilyttää tietoja tietokannasta.
Joten jos logiikan ei pitäisi mennä näkymiin eikä sen pitäisi mennä ohjaimiin eikä sen pitäisi mennä malleihin, niin mihin sen pitäisi mennä?
Tulla sisään tavalliset vanhat Ruby-esineet (PORO). Railsin kaltaisella kattavalla kehyksellä uudemmat kehittäjät ovat usein haluttomia luomaan omia kurssejaan kehyksen ulkopuolella. Logiikan siirtäminen mallista POROihin on kuitenkin usein juuri sitä, mitä lääkäri määräsi välttämään liian monimutkaisia malleja. PORO-palvelujen avulla voit sisällyttää esimerkiksi sähköposti-ilmoitukset tai API-vuorovaikutukset omiin luokkiinsa sen sijaan, että kiinnität ne ActiveRecord
malli.
Joten tämä mielessä, yleisesti ottaen, ainoa logiikka, jonka pitäisi pysyä mallissasi, on:
ActiveRecord
kokoonpano (eli suhteet ja validoinnit)full_name
menetelmä, joka yhdistää first_name
ja last_name
kentät tietokantaan)find
); yleisesti ottaen sinun ei pitäisi koskaan käyttää where
menetelmä tai muut sen kaltaiset kyselynmuodostustavat itse malliluokan ulkopuolellaTämä virhe on eräänlainen seuraus virheestä nro 3 yllä. Kuten keskusteltiin, Rails-kehys painottaa MVC-kehyksen nimettyjä komponentteja (eli mallia, näkymää ja ohjainta). Näiden komponenttien luokkiin kuuluville asioille on melko hyvät määritelmät, mutta joskus saatamme tarvita menetelmiä, jotka eivät näytä sopivan mihinkään kolmesta.
Rails-generaattorit rakentavat kätevästi auttajahakemiston ja uuden auttajaluokan jokaisen luomamme resurssin kanssa. On kuitenkin liian houkuttelevaa alkaa täyttää kaikki toiminnot, jotka eivät muodollisesti sovi malliin, näkymään tai ohjaimeen, näihin auttajaluokkiin.
Vaikka Rails on varmasti MVC-keskitetty, mikään ei estä sinua luomasta omia luokkatyyppejäsi ja lisäämällä sopivia hakemistoja pitämään kyseisten luokkien koodia. Kun sinulla on lisätoimintoja, mieti, mitkä menetelmät ryhmittyvät yhteen, ja etsi hyvät nimet luokille, joilla nämä menetelmät ovat. Railsin kaltaisen kattavan kehyksen käyttäminen ei ole tekosyy hyvien objektipohjaisten suunnittelun parhaiden käytäntöjen päästämiseen.
Ruby and Rails -sovellusta tukee a rikas helmien ekosysteemi jotka yhdessä tarjoavat lähes kaiken mahdollisuuden, jonka kehittäjä voi ajatella. Tämä sopii erinomaisesti monimutkaisen sovelluksen nopeaan rakentamiseen, mutta olen nähnyt myös monia paisuneita sovelluksia, joissa sovelluksen Gemfile
on suhteettoman suuri verrattuna tarjottuihin toimintoihin.
Tämä aiheuttaa useita Rails-ongelmia. Jalokivien liiallinen käyttö tekee Rails-prosessin koosta suuremman kuin sen pitäisi olla. Tämä voi hidastaa tuotannon suorituskykyä. Käyttäjien turhautumisen lisäksi tämä voi johtaa myös suurempien palvelinmuistikokoonpanojen tarpeeseen ja lisääntyneisiin käyttökustannuksiin. Suurempien Rails-sovellusten käynnistäminen vie myös kauemmin, mikä tekee kehityksestä hitaampaa ja tekee automaattisista testeistä kauemmin (ja yleensä hitaita testejä ei yksinkertaisesti suoriteta niin usein).
Muista, että jokainen helmi, jonka tuot sovelluksessasi, voi puolestaan olla riippuvainen muista helmistä, ja ne voivat puolestaan olla riippuvaisia muista helmistä ja niin edelleen. Muiden helmien lisäämisellä voi siten olla yhdistävä vaikutus. Esimerkiksi lisäämällä rails_admin
helmi tuo yhteensä 11 enemmän helmiä, yli 10% enemmän kuin Rails-perusasennuksesta.
Tämän kirjoituksen jälkeen uusi Rails 4.1.0 -asennus sisältää 43 helmiä Gemfile.lock
tiedosto. Tämä on ilmeisesti enemmän kuin sisältyy Gemfile
ja edustaa kaikkia jalokiviä, jotka kourallinen tavallisia Rails-helmiä tuoda riippuvuuksiksi.
Harkitse huolellisesti, onko ylimääräinen yleiskustannus kannattava, kun lisäät jokaisen helmen. Esimerkiksi kehittäjät lisäävät usein rennosti rails_admin
helmi, koska se tarjoaa pohjimmiltaan mukavan web-käyttöliittymän mallirakenteelle, mutta se ei todellakaan ole paljon muuta kuin hieno tietokannan selaustyökalu. Vaikka sovelluksesi vaatii järjestelmänvalvojan käyttäjiä, joilla on lisäoikeuksia, et todennäköisesti halua antaa heille raakaa tietokantakäyttöä ja sinua palvelisi paremmin kehittämällä oma virtaviivaisempi hallintatoiminto kuin lisäämällä tämä helmi.
Vaikka useimmat Rails-kehittäjät ovat tietoisia kehityksen ja tuotannon aikana käytettävissä olevista oletuslokitiedostoista, he eivät usein kiinnitä riittävästi huomiota tiedostojen tietoihin. Vaikka monet sovellukset luottavat lokin seurantatyökaluihin, kuten Mesimäyrä tai Uusi pyhäinjäännös tuotannossa on myös tärkeää pitää lokitiedostojasi silmällä koko sovelluksen kehittämisen ja testauksen ajan.
Kuten aiemmin tässä opetusohjelmassa mainittiin, Rails-kehys tekee sinulle paljon 'taikaa' etenkin malleissa. Assosiaatioiden määritteleminen malleissasi helpottaa suhteiden luomista ja kaiken saatavan saataville. Kaikki malliobjektien täyttämiseen tarvittava SQL luodaan sinulle. Sepä hienoa. Mutta mistä tiedät, että luotava SQL on tehokas?
Yksi esimerkki, johon usein törmäät, on nimeltään N + 1 kyselyongelma . Vaikka ongelma ymmärretään hyvin, ainoa todellinen tapa tarkkailla sen tapahtumista on tarkistaa lokitiedostojesi SQL-kyselyt.
Sano esimerkiksi, että sinulla on seuraava kysely tyypillisessä blogisovelluksessa, jossa näytät kaikki valitun viestikokonaisuuden kommentit:
def comments_for_top_three_posts posts = Post.limit(3) posts.flat_map do |post| post.comments.to_a end end
Kun tarkastelemme tätä menetelmää kutsuvan pyynnön lokitiedostoa, näemme jotain seuraavaa, jossa tehdään kolme kyselyä saadaksesi kolme viestiobjektia, minkä jälkeen tehdään vielä kolme kyselyä saadaksesi kunkin objektin kommentit:
Started GET '/posts/some_comments' for 127.0.0.1 at 2014-05-20 20:05:13 -0700 Processing by PostsController#some_comments as HTML Post Load (0.4ms) SELECT 'posts'.* FROM 'posts' LIMIT 3 Comment Load (5.6ms) ELECT 'comments'.* FROM 'comments' WHERE 'comments'.'post_id' = ? [['post_id', 1]] Comment Load (0.4ms) SELECT 'comments'.* FROM 'comments' WHERE 'comments'.'post_id' = ? [['post_id', 2]] Comment Load (1.5ms) SELECT 'comments'.* FROM 'comments' WHERE 'comments'.'post_id' = ? [['post_id', 3]] Rendered posts/some_comments.html.erb within layouts/application (12.5ms) Completed 200 OK in 581ms (Views: 225.8ms | ActiveRecord: 10.0ms)
ActiveRecord
’S innokas lataus Rails-ominaisuus mahdollistaa kyselyjen määrän merkittävän vähentämisen antamalla sinun määrittää etukäteen kaikki yhdistykset, jotka aiotaan ladata. Tämä tapahtuu soittamalla includes
(tai preload
) -menetelmä rakennettavalla Arel (ActiveRecord::Relation
) -objektilla. Painikkeilla includes
, ActiveRecord
varmistaa, että kaikki määritetyt yhdistykset ladataan käyttämällä mahdollisimman vähän kyselyitä; esim.:
def comments_for_top_three_posts posts = Post.includes(:comments).limit(3) posts.flat_map do |post| post.comments.to_a end end
Kun yllä oleva tarkistettu koodi suoritetaan, lokitiedostossa näemme, että kaikki kommentit on kerätty yhteen kyselyyn kolmen sijaan:
Started GET '/posts/some_comments' for 127.0.0.1 at 2014-05-20 20:05:18 -0700 Processing by PostsController#some_comments as HTML Post Load (0.5ms) SELECT 'posts'.* FROM 'posts' LIMIT 3 Comment Load (4.4ms) SELECT 'comments'.* FROM 'comments' WHERE'comments '.'post_id' IN (1, 2, 3) Rendered posts/some_comments.html.erb within layouts/application (12.2ms) Completed 200 OK in 560ms (Views: 219.3ms | ActiveRecord: 5.0ms)
Paljon tehokkaampaa.
Tämä N + 1-ongelman ratkaisu on todellakin tarkoitettu vain esimerkiksi sellaisista tehottomuuksista, joita sovelluksessasi voi olla 'hupun alla', jos et kiinnitä riittävästi huomiota. Takeaway on, että sinun tulisi tarkistaa kehityksesi ja testata lokitiedostot kehityksen aikana tarkistaaksesi (ja osoite!) Tehottomuudet koodissa, joka rakentaa vastauksesi.
Lokitiedostojen tarkistaminen on loistava tapa kääntää koodisi tehottomuuteen ja korjata ne ennen sovelluksesi tuotantoa. Muussa tapauksessa et voi olla tietoinen seurauksena olevasta Rails-suorituskykyongelmasta, ennen kuin järjestelmäsi käynnistyy, koska tietokokonaisuus, jonka kanssa työskentelet kehityksessä ja testissä, on todennäköisesti paljon pienempi kuin tuotannossa. Jos työskentelet uuden sovelluksen parissa, jopa tuotantotiedostosi voi alkaa pieneltä ja sovelluksesi näyttää toimivan hyvin. Tuotantotiedostosi kasvaessa tämänkaltaiset Rails-ongelmat saavat sovelluksesi kuitenkin toimimaan hitaammin.
Jos huomaat, että lokitiedostosi ovat tukossa joukolla tietoja, joita et tarvitse tässä ovat joitain asioita, joita voit tehdä niiden puhdistamiseksi (tekniikat, jotka toimivat kehityksen kannalta, sekä tuotantolokit).
Ruby and Rails tarjoaa oletusarvoisesti tehokkaat automaattiset testausominaisuudet. Monet Rails-kehittäjät kirjoittavat erittäin hienostuneita testejä TDD- ja BDD-tyylit ja hyödynnä entistä tehokkaampia testikehyksiä, kuten helmiä rspec ja kurkku .
Huolimatta siitä, kuinka helppoa on lisätä automaattista testausta Rails-sovellukseesi, olen kuitenkin ollut yllättävän yllättynyt siitä, kuinka monta projektia olen perinyt tai liittynyt siihen, missä kirjaimellisesti oli ei testit, jotka aikaisempi kehitystiimi on kirjoittanut (tai parhaimmillaan vain hyvin vähän). Vaikka on paljon keskustelua siitä, kuinka kattava testauksesi pitäisi olla, on melko selvää, että ainakin jonkin verran jokaiselle sovellukselle pitäisi olla automaattinen testaus.
Yleisenä nyrkkisääntönä jokaiselle ohjaimien toiminnalle tulisi kirjoittaa vähintään yksi korkean tason integraatiotesti. Jossain vaiheessa tulevaisuudessa muut Rails-kehittäjät haluavat todennäköisesti laajentaa tai muokata koodia tai päivittää Ruby- tai Rails-version, ja tämä testauskehys tarjoaa heille selkeän tavan varmistaa, että sovelluksen perustoiminnot ovat toimi. Tämän lähestymistavan lisäetuna on, että se tarjoaa tuleville kehittäjille selkeän rajauksen sovelluksen tarjoamasta toiminnallisuudesta.
Kolmannen osapuolen Rails-palveluntarjoajat tekevät palvelujensa integroimisesta yleensä erittäin helpoksi API: nsa ympäröivien helmien kautta. Mutta mitä tapahtuu, jos ulkoisella palvelullasi on katkos tai se alkaa toimia hyvin hitaasti?
Välttääksesi näiden puheluiden estämisen sen sijaan, että soittaisit näihin palveluihin suoraan Rails-sovelluksessasi pyynnön normaalin käsittelyn aikana, siirrä ne mahdollisuuksien mukaan jonkinlaiseen taustatyön jonotuspalveluun. Joitakin suosittuja helmiä, joita Rails-sovelluksissa käytetään tähän tarkoitukseen, ovat:
Tapauksissa, joissa käsittelyn siirtäminen taustatyön jonoon on epäkäytännöllistä tai mahdotonta, sinun on varmistettava, että sovelluksessasi on riittävät virheenkäsittely- ja epäonnistumissäännökset väistämättömiin tilanteisiin, kun ulkoinen palvelu menee alas tai jos siinä on ongelmia . Testaa sovelluksesi myös ilman ulkoista palvelua (ehkä poistamalla palvelin, jolla sovelluksesi on käytössä) varmistaaksesi, että se ei aiheuta odottamattomia seurauksia.
Kiskot tietokannan siirtomekanismi voit luoda ohjeita lisätä ja poistaa tietokantataulukoita ja rivejä automaattisesti. Koska nämä siirrot sisältävät tiedostot on nimetty peräkkäin, voit toistaa ne aikojen alusta tuodaksesi tyhjän tietokannan samaan malliin kuin tuotanto. Tämä on siis loistava tapa hallita sovelluksen tietokantamallin tarkkoja muutoksia ja välttää Rails-ongelmat.
Vaikka tämä toimii varmasti hyvin projektisi alussa, ajan myötä tietokannan luomisprosessi voi viedä jonkin aikaa, ja joskus siirrot menevät väärin, lisätään järjestykseen tai tuodaan muista Rails-sovelluksista samalla tietokantapalvelimella.
Rails luo esityksen nykyisestä skeemastasi tiedostossa nimeltä db/schema.rb
(oletuksena), joka päivitetään yleensä, kun tietokannan siirrot suoritetaan. schema.rb
tiedosto voidaan luoda jopa silloin, kun siirtoja ei ole, suorittamalla rake db:schema:dump
tehtävä. Yleinen Rails-virhe on tarkistaa uusi siirto lähdekirjastoon, mutta ei vastaavasti päivitettyä schema.rb
tiedosto.
Kun siirrot ovat päässeet käsistä ja niiden suorittaminen vie liian kauan tai eivät enää luo tietokantaa oikein, kehittäjien ei pitäisi pelätä tyhjentää vanha siirtohakemisto, jättää uusi kaava ja jatkaa sieltä. Uuden kehitysympäristön luominen edellyttäisi sitten rake db:schema:load
pikemminkin rake db:migrate
johon useimmat kehittäjät luottavat.
Jotkut näistä asioista keskustellaan myös Rails Guide -oppaassa.
Rails-kehyksen avulla on helppo luoda turvallisia sovelluksia, jotka ovat läpäisemättömiä monen tyyppisille hyökkäyksille. Osa tästä saavutetaan käyttämällä salaista tunnusta istunnon suojaamiseksi selaimella. Vaikka tämä tunniste on nyt tallennettu config/secrets.yml
: iin ja tiedosto lukee tunnuksen tuotantopalvelimien ympäristömuuttujasta, Railsin aiemmat versiot sisälsivät tunnuksen config/initializers/secret_token.rb
Tämä tiedosto tarkistetaan usein virheellisesti lähdekoodivarastoon muun sovelluksesi kanssa, ja kun näin tapahtuu, kuka tahansa, jolla on pääsy arkistoon, voi nyt vaarantaa kaikki sovelluksesi käyttäjät .
Siksi sinun on varmistettava, että arkiston määritystiedosto (esim. .gitignore
For mennä käyttäjät) sulkee pois tiedoston tunnuksestasi. Tuotantopalvelimesi voivat sitten hakea tunnuksensa ympäristömuuttujasta tai mekanismista, jonka kaltainen dotenv-helmi tarjoaa.
Rails on tehokas kehys, joka kätkee paljon ruma yksityiskohtia, joita tarvitaan a vankka verkkosovellus . Vaikka tämä tekee Rails-verkkosovellusten kehityksestä paljon nopeampaa, kehittäjien tulisi kiinnittää huomiota mahdollisiin suunnittelu- ja koodausvirheisiin varmistaakseen, että heidän sovelluksensa ovat helposti laajennettavissa ja ylläpidettävissä niiden kasvaessa.
Kehittäjien on myös oltava tietoisia asioista, jotka voivat tehdä heidän sovelluksistaan hitaampia, vähemmän luotettavia ja vähemmän turvallisia. On tärkeää tutkia kehys ja varmistaa, että ymmärrät täysin kehitysprosessin aikana tekemäsi arkkitehtuurin, suunnittelun ja koodauksen kompromissit, jotta varmistat korkealaatuisen ja korkean suorituskyvyn sovelluksen.
Liittyvät: Mitkä ovat Ruby on Rails -edut? Kahden vuosikymmenen ohjelmoinnin jälkeen käytän kiskoja