A Rails a Ruby nyelvre épülő nyílt forráskódú, keresztplatformos, MVC (Model-View-Controller) mintára épülő webalkalmazás-keretrendszer. David Heinemeier Hansson írta 2004-ben, a Basecamp program kódjának felhasználásával.
Alapelvei a Don't repeat yourself (ne ismételd magad) és a Convention over Configuration (konvenciók a beállítások előtt): minden információ csak egy helyen szerepel (például egy adatbáziskezelő osztályban nem kell az oszlopokat definiálni, a Rails közvetlenül kiolvassa a nevüket az adatbázisból), és a konvenciókat követő elnevezésekhez automatikusan kódot generál a rendszer (például az adatbázis sales táblája automatikusan hozzárendelődik a Sale osztályhoz). AJAX-támogatása miatt a web 2.0 alkalmazások egyik népszerű keretrendszere.
A Rails keretrendszer az alábbi komponensekből épül fel:
Az imént felsorolt komponensek közül egy egyszerű Rails alkalmazásnak csak az Active Record, Action View és Action Controller hármasra van közvetlenül szüksége, amik rendre az MVC architektúra Model, View és Controller részei. A továbbiakban erről a három komponensről lesz szó.
A Ruby (Windows alatt: RubyInstaller) telepítése után a legegyszerűbben a rubygems segítségével telepíthetjük a Railst, a következő parancs kiadásával:
A rubygems feltelepít mindent, amire szükségünk van a Rails használatához, beleértve egy egyszerű webszervert (WEBrick) és egy adatbázist (SQLite). Természetesen használhatunk mást is, a Rails ismeri többek között a MySQL és PostgreSQL adatbázisokat, és használható Apache, lighttpd, nginx, stb. webszerverekkel.
A telepítés után a "rails" és a "rake" parancsokkal tudunk új rails alkalmazást létrehozni. A "rails" programot használjuk az alkalmazásunk komponenseinek generálására, a szerver elindítására, stb. A "rake" (Ruby mAKE) parancs különféle szkriptekkel segíti munkánkat, mint például az adatbázis adminisztrálása. Egy "Blog" nevű alkalmazás vázát a következő parancs kiadásával tudjuk létrehozni:
Ez az aktuális könyvtárunkon belül egy "blog" könyvtárat hoz létre, majd azon belül számos alkönyvtárat és fájlt. Ezekről részletesebben a Szerkezet pontban lesz szó. A blog könyvtárba belépve és onnan a szervert elindítva ellenőrizni tudjuk, hogy sikeres volt-e a rails telepítése és az alkalmazásunk generálása:
A böngészőnkben a localhost:3000 címre navigálva meg kell jelennie a Rails üdvözlő oldalának.
A scaffolding nevű művelettel tudunk automatikusan adatbázis sémákat reprezentáló osztályokat generálni.
Példa:
Ez létrehozza az adatbázisban a posts nevű táblát, ami tartalmazza a fenti oszlopokat, a Post nevű osztályt, ami ennek elérésére szolgál, továbbá a viewhez tartozó html fájlokat a tábla elérésére és módosítására. A második sor azért kell, mert a scaffold parancs valójában nem módosítja az adatbázisfájlunkat, hanem e helyett létrehoz egy "migrate" fájlt. A migrate fájlok segítségével bármikor újra tudjuk építeni az adatbázist.
Végül a routes fájlba bekerül a "resources :posts" sor, ami mindezek elérését teszi lehetővé. A localhost:3000/posts címen megjelenik az összes Post listája, a /posts/<id> címen az id azonosítójú Postot találjuk (például a 2. sorszámút a /posts/2 címen), illetve a /posts/<id>/edit címen szerkeszthetjük azt.
Ebben a pontban az előbbiek során generált fájlok szerepéről lesz szó. Az átláthatóság érdekében a kevésbé lényeges elemeket nem említjük meg.
A Rails konzolban kézzel tudunk a létrehozott modellekkel dolgozni, például új elemeket létrehozni, vagy lekérdezéseket futtatni. A Rails konzolt kétféleképpen indíthatjuk el:
Sandbox módban indítva a Rails minden módosításhoz létrehoz egy rollback bejegyzést, és a konzolból kilépve visszaállítja az eredeti állapotot, egyébként minden változtatás végleges lesz. A Rails konzol a Ruby IRB(Interactive Ruby) shelljét használja, és tetszőleges Ruby vagy Rails utasításokat futtathatunk benne, többek között a következő pontban ismertetett CRUD műveleteket.
Hasznos lehet még a következő parancs, ami a használt adatbázisunk konzolját indítja el (feltéve, hogy telepítve van):
A CRUD a Create, Read, Update, Delete rövidítése, ami az adatbázis-műveletek összefoglaló neve. Ezeket a műveleteket támogatják a scaffoldinggal generált modellek.
Új elemet a new vagy create műveletekkel tudunk létrehozni. A new művelet visszaad egy objektumot, aminek a save függvényét meg kell hívni, hogy az belekerüljön az adatbázisba. Ezzel szemben a create művelet azonnal létrehozza az elemet, így minden kötelezően kitöltendő mezőt meg kell adnunk az argumentumában. Az elem azonosítóját ("id" mező) nem kell megadnunk: az Active Record gondoskodik arról, hogy egyedi azonosítóval kerüljön bele az adatbázisba.
Példák elem létrehozására:
Az elemeket a népszerűbb adatbázisokból már ismerős kulcsszavakkal tudjuk olvasni, mint "where", "order", "count", "limit", stb. Az első sorban lévő kód egyetlen elemet ad vissza, a második és harmadik sorban lévők pedig egy tömböt (feltéve, hogy van ilyen azonosítójú elem).
Példák az adatbázis olvasására:
A find művelet az elemek azonosítója alapján keres. Van lehetőség bonyolultabb feltételeket is megadni vagy más mezők alapján keresni a where használatával:
A metódusokat tetszőlegesen láncolhatjuk egymás után:
Ha egy where lekérdezésbe változót szeretnénk behelyettesíteni, akkor azt a ? karakterrel tehetjük meg:
Megjegyzés: habár a Rubyból ismert "változó helyettesítése stringbe" módszer is működik, célszerű minden esetben az előző szintaxist használni, ugyanis közvetlen szöveges helyettesítéssel sebezhetővé tesszük a programunkat az SQL injection támadásokkal szemben:
Az első példában az escape karaktereket automatikusan kiszűri a where metódus változóhelyettesítése.
Az attributes/save és update_attributes közötti különbség ugyanaz, mint feljebb a new és a create között.
Példák elemek szerkesztésére:
Példák elemek törlésére:
Az utóbbi az összes elemet törli a táblából.
A modellünk az adatbázishoz hozzáférést biztosít az alkalmazásunk számára, és felügyeli, hogy ne sérüljenek meg az adatbázis integritását védő invariánsok.
A scaffolding pontban generált Post modell kódja a következő:
A modellt különféle makrókkal és függvényekkel bővíthetjük ki. Egy ilyen makró a fent látható "attr_accessible", ami után felsorolt mezők írhatók lesznek formok és URL paraméterek segítségével. Ha egy lapunk olyan mezőt próbál írni, ami itt nincs felsorolva, akkor hibaüzenetet kapunk.
Hasonló makrók a "before" és "after" makrók. Segítségükkel megadhatunk függvényeket, amelyek mindig lefutnak az előtt vagy az után, hogy egy elemet lekérdezünk, létrehozunk, módosítunk vagy törlünk. A példa kedvéért tegyük fel, hogy a táblánkat kibővítettük egy "date" mezővel, ahol a Post létrehozásának napját tároljuk, de ehez a mezőhöz nem akarunk hozzáférést adni a kliensnek, továbbá azt automatikusan akarjuk beállítani. Ezt a következő változtatással tehetjük meg:
A fill_date függvény le fog futni minden alkalommal, amikor létrehozunk egy elemet, és beállítja a date mezőt.
Hasonló makrókkal tudjuk validálni a mezők értékeit. Ha scaffold segítségével generáltuk a modellhez tartozó view-t, akkor a validáció sikertelensége esetén a lapon automatikusan megjelenik a megfelelő szöveges hibaüzenet, és felszólítja a felhasználót, hogy javítsa ki a megfelelő mezőt.
Példa: name és title mező ne legyen üres, és a title legalább 5 karakter hosszú legyen:
Példa: Egyszerű validáló regex e-mail formátumra:
A validációkban leírt feltételek teljesülését kétféleképpen is vizsgálhatjuk. Az eddig látott perzisztáló műveletek (pl save) visszatérési értéke jelzi, hogy az adott művelet sikeres volt-e. A másik lehetőség e műveletek ! jeles változata, amely kivételt dob. Ezek után az objektum errors mezőjében találhatjuk meg a valódációs hibák részleteit.
Példa: Post name mezőjét üresen hagyjuk
Modellek közötti kapcsolatokra azért van szükségünk, hogy a különböző műveleteket egyszerűbben tudjuk végrehajtani. Képzeljünk el egy példát, amiben két modellünk van: vásárló és megrendelés.
Kapcsolat nélkül az alábbi módon fog kinézni:
Ahhoz, hogy egy vásárolóhoz új megrendelést vegyünk fel, ezt kell csinálnunk:
Amennyiben egy vásárló törlésénél a megrendeléseit is szeretnénk kitörölni, az alábbi módon tehetjük meg:
Az ActiveRecordnak köszönhetően ezeket lényegesen egyszerűbben is megvalósíthatjuk, azzal, hogy megmondjuk a rails-nek, hogy a két modell kapcsolatban áll egymással:
Ezekkel a változtatásokkal egy új megrendelés létrehozása lényegesen rövidebb:
Még ennél rövidebbé vált a vásárló és a hozzá tartozó megrendelések törlése:
Railsben az asszociációk kapcsolatok két ActiveRecord modell között. Az asszociációkat makró-szerű hívásokkal határozhatjuk meg. Például, ha egy modellnél meghatározzunk, hogy belongs_to másik modell, azzal a Railsnek azt mondjuk, hogy egy primary key-foreign key információt tároljon a két modell példányaiban.
Hat különböző kapcsolatot használhatunk Rails-ben:
A belongs_to kapcsolat egy egy-az-egyhez kapcsolatot létesít két modell között, úgy hogy a modellünk egy példánya a másik modell egy másik példányához tartozik. Például, ha van egy vásárló és megrendelés modellünk, és egy megrendelés csak egy vásárlóhoz tartozhat, akkor ezt így definiálhatjuk a megrendelés modellben:
A has_one kapcsolat szintén egy egy-az-egyhez kapcsolatot létesít, akárcsak a belongs_to, de más a jelentése. A modellünk minden példánya tartalmaz egy példányt a másik modellből. Például, ha minden vásárlónknak egy számlája lehet csak, akkor az alábbi módon definiálhatjuk ezt:
A has_many kapcsolat egy egy-a-többhöz kapcsolatot reprezentál két modell között. Gyakran a másik oldala a belongs_to kapcsolatnak. Az adott modell minden példánya nulla vagy több példányát tartalmazza a másik modellnek. A vásárló és megrendelés példánál maradva, egy vásároló több megrendelését az alábbi módon ábrázolhatjuk a modellek között:
A has_many :through kapcsolatot több-a-többhöz kapcsolatnál használjuk egy másik modellen keresztül. A kapcsolat azt jelenti, hogy az adott modell példányai összekapcsolhatók nulla vagy több példányával egy másik modellnek, egy harmadik modellen keresztül. Példának nézzünk egy egészségügyi alkalmazást, ahol a betegek időpontot foglalhatnak az orvosokhoz.
A has_many :through kapcsolat hasznos, ha egymásba ágyazott has_many kapcsolatokat szeretnénk rövidíteni. Például egy dokumentumnak több fejezete van, a fejezeteknek pedig több bekezdésük.
Azzal, hogy through: :sections-t írtunk, a Rails tudni fogja az alábbit hívást értelmezni
A has_one :through kapcsolat egy egy-az-egyhez kapcsolatot létesít egy másik modellel. Ezzel a kapcsolattal azt mondhatjuk meg, hogy az adott modell példányai összekapcsolhatók egy másik modell példányával egy harmadik modellen keresztül. Például, ha egy vásárlónak egy számlája van és minden számlának egy számla története van.
A has_and_belongs_to_many kapcsolat egy direkt több-a-többhöz kapcsolatot jelent egy másik modellel, közbeeső modell nélkül. Például ha van együttes és helyszín modellünk és egy együttes több helyen is felléphet, de egy helyen több együttes is felléphet, akkor ezt az esetet így jelölhetjük:
Ahhoz, hogy egy-az-egyhez kapcsolatot fejezzünk ki két modell között, az egyikhez has_one-t kell adnunk, a másikhoz pedig a belongs_to-t. A különbség, hogy melyiket melyikhez írjuk az, hogy amelyik modellhez kerül a belongs_to, annál lesz a foreign key. Ezen kívül vegyük figyelembe a modellek jelentését is. A has_one kapcsolat azt jelenti, hogy valami hozzád tartozik. Például több értelme van annak, hogy egy vásárlónak van számlája, mint annak, hogy egy számlának van egy vásárlója. Ebben az esetben tehát:
Railsben két különböző lehetőségünk van több-a-többhöz kapcsolatot létesíteni modellek között. Az egyszerűbb megoldás a has_and_belongs_to_many, amivel közvetlenül két modell között teremthetjük meg a kapcsolatot.
A másik lehetőségünk a has_many :through. Ebben az esetben egy harmadik modellen keresztül teremtjük meg a két modell közti több-a-többhöz kapcsolatot.
A szabály arra, hogy mikor használunk has_many :through-t, hogy ha szeretnénk a harmadik modellel - ami a kapcsolatot teremti a két modell között - is önállóan foglalkozni, akkor ezt használjuk. Ha nincs szükségünk a kapcsoló modellre, mint önálló entitásra, akkor a has_and_belongs_to_many kapcsolatot használjuk.
A has_many :through használatára vagyunk korlátozva, ha szeretnénk validációt vagy extra attribútumokat a kapcsoló modellben.Megadhatjuk azt is hogy törlés esetén mi történjen a kapcsolt objektumokkal. Ezt a dependent segítségével tehetjük meg. A következő opciók lehetségesek:
Az alapértelmezett viselkedés a nullify.
Mivel a dependent callbackek segítségével van implementálva, ezért ha olyan művelettel törlünk ami figyelmen kívül hagyja a callbackeket (pl delete) akkor a dependent által megadott akció se fog lefutni.Általános eset hogy egy lekérdezés eredményeként megkapott objektumok kapcsolt objektumait szeretnék elérni. Ebben az esetben minden eléréskor újabb lekérdezést futtatunk le ami nagy mennyiségű adat esetén jelentősen ronthat a teljesítményen. Ilyenkor érdemes a kapcsolatokat mohón előre betölteni. Erre két lehetőségünk van ami az adatok kapcsolásának módjában különböznek:
Mindkettő paraméterként a betölteni kívánt kapcsolatok szimbólumait várja.
Példa: Ebben az esetben nem használunk mohó betöltést a kliensekhet tartozó címek elérésekor ezért 11 lékerdezést végzünk.
Példa: Az includes használatával a lekérdezések száma 2-re csökken
A polimorfikus kapcsolatok lehetővé teszik, hogy egy belongs_to kapcsolat másik oldalán többféle típusú objektumok is lehessenek. Ehhez azonban szükség van kapcsolatnév_id-n kívül plusz mezőre kapcsolatnév_type néven az adatbázisban. Továbbá a belongs_to oldalon a „polymorpic”-ot igazzá kell tenni míg másik oldalakon az „as”-nek át kell adni a polimorfikus kapcsolat szimbólumát.
Az alábbi példában több model is „lájkolhatóvá” szeretnénk tenni. A Like likeable polimorfikusan kapcsoljuk az adott like tárgyát ami esetünkben Post vagy Comment lehet.
A rails-ben egy tábla nemcsak egy osztály , hanem egy osztályhierarchia példányainak is megfelelhet. Ilyen származtatáskor az activerecord specifikus tulajdonságok(pl validációk, kapcsolatok,callbackek) is öröklődnek. Használatához szükség van a táblában egy string típusú type mezőre, illetve a származási hierarchiában előforduló összes adatmezőre a táblában. A type tartalmazza majd, hogy mely osztály példányát írja le az adott rekord. Fontos megjegyezni, hogy bármely résztvevő osztály példánya esetén az adatbázisban megjelenik az összes mező. Emiatt olyan esetekben érdemes használni ezt az eszközt mikor sok a közös adat az osztályok között, hogy elkerüljük sok felesleges null értékekkel járó optimalizálatlanságot.
Példa: Többféle posztot különböztetünk meg. Vannak csak egyszerű szöveges posztok és képes posztok. A közös bennük az hogy mindkettőt egy usernek kellett kiposztolna, illetve hogy kell lennie címüknek.
Ha olyan modulokat szeretnénk készíteni amik activerecord makrókat tartalmaznak akkor érdemes Concernekkel megoldani mivel ebben az esetben a használatuk kényelmesebb mint az egyszerű moduloké.
Példa: Egy scopet akarunk megosztani ami azt mondja meg mikor tekintünk egy objektumot kikapcsoltnak.
Az egymásra épülő modulok függőségeinek kezelése is egyszerűbb. Egyszerű modulba nem tudunk könnyedén másik modult beágyazni ezért a használó osztálynak kell gondoskodnia arról, hogy egy adott modul összes függőségét is beágyazza. Ezzel szemben egy concern közvetlenül beágyazhat egy másik concern-t.
Példa: Bar modulban szeretnénk egy Foo modulban lévő metódust használni.
Osztálymetódusok helyett érdemesebb scope-kat használni a gyakran hivatkozott lekérdezések leírására a modell osztályokban. A kényelmesebb lambda szintaxis mellett nagy előnyük, hogy probléma nélkül egymáshoz láncolhatóak.
Példa: Az 1 héttel ezelőtt készül már publikált posztok
A viewhez .erb (Embedded Ruby) fájlok tartoznak. Ezekben a fájlokban vegyesen található HTML és Rails kód. A kód HTML-be ágyazásának két fajtája van:
A <% kezdetű kódot csak végrehajtja, a <%= kezdetűnek viszont be is helyettesíti az eredményét a HTML fájlba.
Hogy a HTML oldalak megegyező részeit (például fejléc, menük, stb.) ne kelljen minden egyes oldalon megismételnünk, layout-okat hozhatunk létre.
A yield helyére kerül be az aktuális oldal saját kódja, a flash pedig akkor jelenik meg, ha az előző oldalon beállítottuk a notice változót, amiben a felhasználónak szánt üzeneteket tárolhatjuk, például „Az új elem létrehozása sikeres.”. A Rails a stylesheet_link_tag helyére az app/assets/stylesheets könyvtárban lévő css fájlokat linkeli, a javascript_include_tag esetében hasonlóan javascript fájlokra. A csrf_meta_tags egy kódot generál, ami véd a Cross-site request forgery támadások ellen.
A layout-hoz hasonlóan az ismétlések csökkentésére használható eszköz. A parciálisokat külön fájlban kell tárolni, továbbá a fájl nevének „_” karakterrel kell kezdődnie. A parciális tartalmát a render metódus segítségével lehet beszúrni a megfelelő helyre. A hívás pontjában elérhet objektumszintű változókat a parciálisban is elérjük. Egy parciálison belül is beszúrhatunk parciálisokat.
Példa: A post szerkesztéséhez és új hozzáadásához ugyanazt az űrlapot tudjuk használni ezért azt kiszervezzük egy parciálisba.
A render hívása során lehetőségünk van a lokális paraméterek átadására is.
Parciálisok számára is létrehozhatunk layoutokat ezek a parciális layoutok. Különbség az eddigi layouthoz képest hogy ezek a parciális layoutok a parciálisok elnevezési konvencióját követik, továbbá nem a layouts mappában, hanem a használni kívánó parciálisokkal egy mappában foglalnak helyet.
A parciálisokat nagyon kényelmesen lehet gyűjtemények megjelenítésére használni.
Példa: Az alábbi esetben a @prodcuts összes elemére megjeleníti a _product parciálist.
Elemekre, oldalakra, műveletekre linkeket többféleképpen is el tudunk helyezni. A scaffold művelet a következő pathokat generálja a Post táblához:
Linkeket a link_to függvénnyel tudunk létrehozni. A link_to első paramétere a link szövege, a második pedig a linkelni kívánt oldal. Az első példában az oldalon a "Show All Posts" szöveg fog megjelenni, a link pedig a posts_path-ra fog mutatni (a mi esetünkben ez a localhost:3000/posts cím)
A következő link szövege a "post"-nak a title mezőjében tárolt stringje lesz, a link pedig az ezt a postot szerkesztő oldalra (localhost:3000/posts/<post.id>/edit) fog mutatni. Érdemes megfigyelni, hogy a pathoknak meg tudunk adni paramétert is, ami itt a "post".
A linkeknek megadhatunk egyedi paramétereket is. Például a következő link a "localhost:3000/posts?sort=name" címre fog mutatni. Természetesen magát a rendezést nekünk kell majd megvalósítani a controllerben. Ennek a példának a másik fele a következő pontban szerepel.
A controllerek a programunk magját és logikáját foglalják magukban. Értelmezik a bejövő kérelmeket, végrehajtják a megfelelő akciókat, kommunikálnak a modellel és előkészítik a megjelenítendő adatokat, amiket tovább adnak a view-nek. Egy frissen generált Rails alkalmazásnak egyetlen controllerje van, a neve ApplicationController. Az osztály majdnem teljesen üres, a célja az, hogy ide helyezzük az egész alkalmazásra nézve globális változókat és segédfüggvényeket. A scaffold parancs minden modell mellé létrehoz egy controllert is, jelen esetben a PostsController osztályt ami a következő függvényeket tartalmazza:
A new, edit, create, update és destroy függvények neve magáért beszél. Az index függvényt akkor használjuk, ha az összes postot meg akarjuk jeleníteni, a showot pedig akkor, ha csak egy postra vagyunk kíváncsiak. Utóbbinál a show paramétere a post azonosítója.
Vizsgáljuk meg most közelebbről például a destroy függvényt.
A függvény első sorában látható params[:id] az URL-ből próbálja meg kinyerni a paramétert. Az automatikusan generált komment segít megérteni a függvény működését: a "DELETE /posts/1" kérelemnél a DELETE a végrehajtandó akció (a routing gondoskodik arról, hogy ez a kérelem a PostsController destroy függvényéhez kerüljön), az "1" pedig a paraméter, esetünkben a params hash :id mezője.
Tehát behelyettesítve, az első sorban a Post.find(1) visszaadja az 1-es azonosítójú postot, amit a @post változóban tárolunk, majd meghívjuk a destroy függvényét. A @-al kezdődő változók instance változók, ami számunkra azért fontos, mert a view el tudja érni őket. A View pont első példájában látható @posts változót hasonlóan a controller hozta létre.
A függvény második felének viselkedése a kérelem formátumától függően változik. JSON esetén egy üres objektumot kapunk válaszként, HTML esetében pedig a controller átirányítja a böngészőt a posts_url pathra.
Az előző pont egyik példájában szerepelt a következő link:
A posts_path a PostsController index akciójára mutat, tehát ha szeretnénk implementálni ezt a funkciót, akkor azt kell kibővítenünk:
A "sort" paramétert hasonlóan tudjuk elérni, mint az előbbi példánál az "id" paramétert. A linkre kattintva az index függvényhez kerül az irányítás, a params[:sort] értéke pedig "name" lesz. Innentől például egy elágazással tudjuk a megfelelő értékekkel feltölteni a @posts változót.
Az oldal elérésére szolgáló URL-ek formáját könnyedén testre szabhatjuk a routinggal. A routing adatokat a config/routes.rb fájlban találjuk.
Az első sor a Post osztály pathjait tartalmazza, mint például a korábban említett new_post_path, posts_path, stb.
A routing segítségével alapvetően URLeket rendelünk hozzá controllerek akcióihoz. Egy route céljánál a # előtt szerepel a controller, utána pedig az akció, például posts#index a PostsController index akciójára mutat. A második sorban a localhost:3000/list_posts URL-t rendeljük hozzá a postok indexeléséhez. A harmadik sorban pedig a localhost:3000/view_post/<id> URLt a posts controller show akciójához, ahol a params[:id] értéke az utolsó / után szereplő érték lesz. Végül az utolsó sorban azt adhatjuk meg, hogy ha valaki megnyitja a localhost:3000/ címet, akkor melyik akcióhoz kerüljön a kérelem.
A rails szervert alapvetően két különböző módban indíthatjuk el: development és production. Az ezekhez tartozó beállításokat a config/environment könyvtár development.rb és production.rb fájljai tartalmazzák. Számos különbség van a kettő között: például ha egy nem létező URL-re vagy Post-ra hivatkozik egy kliens, akkor development módban egy részletes hibaüzenet jelenik meg trace és az aktuális paraméterekkel együtt, production módban viszont csak egy sablon 404-es oldal, ezért érdemes az alkalmazás fejlesztését (az alapértelmezett) development módban végezni. Külön adatbázist is használ a két környezet, ezek alapértelmezetten a db/development.sqlite3 és production.sqlite3 fájlokban vannak. Nem utolsó sorban production módban a webszerver lényegesen gyorsabb.
Az átállás a production környezetre nem teljesen triviális. Először célszerű felépíteni a production adatbázist:
A következő probléma, hogy development módban a rails hajlandó futás közben fordítani a css, javascript és egyéb fájlokat, de production módban ez nem megengedett, így a következő parancs kiadásával le kell fordítanunk őket (a parancsot minden változtatás után újra ki kell adni):
Alternatív megoldás lehet, ha módosítjuk a production.rb fájlt: a "config.assets.compile = false" sor "true"-ra átírásával engedélyezhetjük a futás közbeni fordítást. Valódi alkalmazásoknál ez nem javasolt, mert lassítja a szervert.
Ha az alkalmazásunkat WEBrickkel teszteljük, akkor ugyanebben a fájlban a "config.serve_static_assets = false" sort állítsuk "true"-ra, különben production módban a statikus elemek, mint például képek és stylesheetek nem lesznek elérhetők. Egyéb webszervernél, mint Apache és nginx a statikus oldalakat célszerű, ha a rails helyett a szerver szolgálja ki, így ebben az esetben ezt a sort ne módosítsuk.
Végül indítsuk el a szervert, mostmár production módban:
Ruby on rails-ben számos webes funkciót pl. authentikáció, layout-ok stb. megvalósítottak már, amik elérhetőek a githubon mind a forráskóddal, mind a hozzájuk tartozó manuallal. Ezek egyszerű package-k, amikben az installációhoz szükséges file-ok és a package információk vannak. Egy-egy gemet a gem paranccsal lehet feltelepíteni, illetve leszedni:
$ gem install _mygem_
$ gem uninstall _mygem_
Továbbá a gépen már elérhető gemeket a
paranccsal lehet kilistázni.
Másik módja az installálásnak, ha a Gemfile-ba írjuk a gemet, majd bundle install-t adunk ki:
Authentikációt megoldó gem, amely megengedi, hogy egyszerre több user is be legyen jelentkezve. Konfigurálása:
Ezután a terminálban leírtakat kell követni, megmondja, melyik filet, hogyan updateld. Ha az megvan, lehet generálni a User modelt:
Ez után mindig újra kell migrálni az adatbázist, majd újraindítani a servert:
$ rake db:migrate
$ rails s
Elérhetősége: https://github.com/plataformatec/devise
Authorizáció megoldására kitalált gem. Egyszerűen lehet vele definiálni és elérni a felhasználói jogokat, továbbá a kivételkezelés is meg van benne valósítva. Minden jog az Ability class-ban definiálva és nem ismétlődik egyetlen controllerben vagy akár viewban sem. A szokásos telepítés mellett
Gemfileba: gem 'cancan'
$ bundle install
pluginként is installálható
$ rails plugin install git://github.com/ryanb/cancan.git
Elérhetősége: https://github.com/ryanb/cancan
A Haml (HTML abstraction markup language) a viewkban levő kódot engedi átláthatóbban megírni, egy egyszerű szintaxis biztosításával. Példakód:
<section class=”container”> <h1><%= post.title %></h1> <h2><%= post.subtitle %></h2> <div class=”content”> <%= post.content %> </div> </section> |
=> |
%section.container %h1= post.title %h2= post.subtitle .content = post.content |
Elérhetősége: http://haml.info/
Ez egy olyan keretrendszer, ami pontosan ugyanazt csinálja a CSS-sel, amit a Haml a HTML-lel.
Elérhetősége: http://compass-style.org/
Front-end framework a webfejlesztéshez, ami tartalmazza a szükséges css, javascript elemeket és fontokat. Rails 4, 3.1, 3.2 támogatott
bootstrap/
|--css/
| |--bootstrap.css
| |--bootstrap.min.css
| |--bootstrap-theme.css
| |--bootstrap-theme.min.css
|--js/
| |--bootstrap.js
| |-- bootstrap.min.js
|--fonts/
|--glyphicons-halflings-regular.eot
|--glyphicons-halflings-regular.svg
|--glyphicons-halflings-regular.ttf
|--glyphicons-halflings-regular.woff
Elérhetősége: http://getbootstrap.com/
A Bootstraphez hasonló gem. Ezesetben a Gemfileba az alábbiakat kell írni:
vagy
gem 'foundation-rails'
Konfigurációja hasonlóan a devise-hoz:
Elérhetősége: http://foundation.zurb.com/
Social networkot támogató gem, amiben meg támogatja az ismert: like, follow, taggelés (a gemben mention néven fut).
Ez legenerálja mind a három említett modelt (follow, like, mention), amiket probléma nélkül lehet törölni később, ha még sincsen rájuk szükség. Metódusai a
Hasonlóan az act_as_likeable, act_as_mentionable és ezek párjai.
Elérhetősége: https://github.com/cmer/socialization
Ruby verzió >= 1.9.2 , Rails verzió >= 3.0
Ezt a gemet azért találták ki, hogy a fájlok kezelése (feltöltése) éppen olyan egyszerű legyen, mint bármelyik attribútumnak a megvalósítása. Igény szerint lehet thumbnails-zá transzformálni a képeket, ehhez viszont az ImageMagick szükséges
A feltöltött file-ok a filerendszerbe kerülnel és a browserból lehet rájuk hivatkozni.
Elérhetősége: https://github.com/thoughtbot/paperclip
Megnyitja előnézetre a levelet a böngészőben, mielőtt elküldené. Így nem kell a fejlesztőkörnyezetben beállítani az email kézbesítést, elkerülve ezzel azt, hogy véletlenül rossz címre küldjünk levelet.
Gemfileba: gem "letter_opener", :group => :development
$ bundle install
Továbbá az alábbi metódust kell még hozzá beállítani a config/environments/development.rb fileban:
Ezek után minden email egy pop-upként jelenik meg a küldés helyett, és a /tmp/letter_opener-ben lesznek letárolva.
Elérhetősége: https://github.com/ryanb/letter_opener