Sunteți pe pagina 1din 38

Abstract: Rails este o aplicatie web revolutionara pentru dezvoltarea aplicatiilor web cu

gestiune de baze de date. Rails se remarca dintre alte zeci de astfel de aplicatii ce pot fi gasite
in intreaga lume prin aceea ca permite un cadru software de lucru in care dezvoltarea
aplicatiilor se face de aproximativ 10 ori mai rapid decat in cazul mediului Java. Rails se
poate integra deasemeni cu Java, Visual Studio 2005, MySql si Sql, javascript, Rhtml, CSS,
php, etc. Rails este urmatoarea generatie in programarea web, iar dezvoltatorii ce il folosesc
vor realiza aplicatii web mai rapid decat aceeia care nu il folosesc. Ruby on Rails face
dezvoltarea softwareului simpla. Se reazizeaza rapid. Este amuzanta. Si cel mai mult? Rails
este disponibila, pe gratis, chiar acum, sub licenta de sursa deschisa MIT (open source MIT
license).

Rails
Iata pe scurt cateva din caracteristicile Rails (in traducere libera: "Sine") conform site-ului
companiei dezvoltatoare Aptana ( http://www.aptana.com/ ):
- Suport unificat pentru Ruby, Rails, Rhtml .... si JS, HTML, CSS!
- marcarea sintaxei, autofinalizare, asistenta codarii, raportarea erorilor, conturarea (schitarea),
etc
- Generarea de cod Ruby: constructori suprascrieri, sabloane, accesorii
- Refactorizarea: variabileleor locale la variabile de instanta, extragerea metodelor, inserarea
de cod inline, redenumirea ...
- Debugger rapid si integrat
- Suport pentru generatoare Rails, Rake, plugins-uri (aplicatii auxiliare), si managementul de
server
- Vizualizarea unitatilor de test si a rezultatelor testarii
- Analiza integrata a codului
- Navigator incapsulat de baze de date si consola de interogare
- Retete cu exemple (snippets) si programe de asistare programator (wizzards)
- Ajutor (Help) integrat, incluzand "Mergi la definitie", "RDoc/RI", si explorator de cod
- Completa integrare cu urmatoarele medii: C++, C, C#, Ch, Asembler, Java, IDL, JavaScript,
Flash (ActionScript 2) files, Perl, Lisp, XML, SQL, *.html;*.htm;*.asp;*.shtml;*.htd;*.jsp,
Visual Basic, Matlab, Fortran, ADA si multe altele. vezi: http://www.rubyonrails.org/docs
Prin urmare Rails este o aplicatie web si un cadru de lucru ce include tot ce este necesar
pentru a creea aplicatii web cu baze de date in acord cu comportamentul de separare ModelAfisare-Control (Model-View-Control). Acest comportament imparte afisarea (deasemeni
numita prezentare) in sabloane "mute" care sunt responsabile in primul rand de inserarea
datelor pre-construite intre instructiunile HTML. Modelul contine obiecte de domeniu
inteligent (precum Cont, Produs, Persoana, Posta) ce inregistreaza toata logica afacerii si
cunoaste cum sa persiste in baza de date. Controlereul gestioneaza cerintele ce vin (ca de
exemplu Salveaza Cont Nou, Improspateaza Produs, Afiseaza Posta) prin manipularea
modelului si directionarea datelor catre afisare.
In Rails, modelul este gestionat de ceea ce se numeste nivel (strat) de cartografiere obiectrelational numit Inregistrare Activa. Acest nivel (strat) permite prezentarea datelor din

randurile bazei de date ca obiecte si infrumusetarea acestor obiecte de date cu metode de


logica pentru afaceri.
Controller-ul si afisarea sunt gestionate de catre pachetul de actiune, care manipuleaza ambele
nivele (straturi) prin cele doua parti ale sale: Afisarea Actiunii si Controllerul de Actiune.
Aceste doua straturi sunt incapsulate intr-un singur pachet datorita Inregistrarii Active si
Pachetului de Actiune care este mult mai separat. fiecare din aceste pachete poate fi folosit in
mod independent in afara Rails.
La baza Rails sta un limbaj de programare numit Ruby.
Ruby este un libaj de programare pur orientat pe obiecte cu o sintaxa super-clara ceea ce face
programarea eleganta si distractiva. Ruby combina cu succes eleganta conceptuala a
Smalltalk, usurinta in utilizare si invatare a lui Python, si pragmatismul lui Perl. Ruby isi are
originile in Japonia la inceputul anilor 1990. Acesta a devenit popular in intreaga lume foarte
recent in ultimii ani cu cat si-au facut apartitaia din ce in ce mai multe carti si documentatia in
limba engleza (si popularitatea sa in mod real si-a luat zborul de la introducerea Rails!)
Un exemplu practic:
Programatorii dezvoltatori sunt obisnuiti sa auda in mod excesiv o supra-acompaniere asupra
unui lucru nou. Este un lucru cunoscut. Prin urmare sarind peste ccea ce se numeste o credinta
oarba iata un exemplu ilustrativ care va dovedi aceste afirmatii asupra calitatilor deosebite ale
Rails (vezi si http://www.onlamp.com/pub/a/onlamp/2006/12/14/revisiting-ruby-on-railsrevisited.html ):
Pentru a fi mai usor de parcurs si a avea "sare si piper" am conceput aceasta prezentare sub
forma unei mici pise de teatru intre un sef si un angajat. La sfarsitul prezentarii acestui exemplu

este foarte probabil ca orice cititor sa fie motivat si gata de invatare a folosirii mediului Rails Acest
exemplu recent va produce o aplicatie care arata si care are exact aceleasi caracteristici ca si
originalul. In loc sa presupunem ca in loc sa ne apucam noi sa proiectam aceasta aplicatie pentru
prima data haide-ti sa presupunem ca seful vine in biroul nostru chiar inainte de masa de pranz si
spune:
Seful: Hei CB (adica noi). sunt intr-o incurcatura. AM mare nevoie de ajutorul dumneavoastra. am
programata o prezentare pentru seful meu maine dimineata. am facut o mica aplicatie pentru el in
graba. Este vorba de o mare afacere cu el si cred ca el urmeaza sa invite si alti parteneri de afacere
la aceasta demonstratie maine. Poate chiar pe seful lui direct! Problema este ca am folosit un
consultant extern pentru aceeasta aplicatie iar, el se pare ca a castigat la lotto azi-noapte. El nu a
venit azi de dimineata , nu mi-a raspuns la e-mailuri si nici nu a raspuns la telefonul mobil. Si colac
peste pupaza aplicatia a incetat sa functioneze cu aproximativ o ora in urma din niste motive
necunoscute iar, eu nu sunt in stare sa gasesc nici macar codul sursa. CB, asta nu este sfarsitul
povestii pe care vreau sa o prezint sefului meu maine dimineata in biroul sau personal. Se zvoneste
pe la discutiile la o cafea ca voi ati incercat sa obtineti aprobarea pentru o noua unealta de
dezvoltare software. Ati spus ca aceasta va da posibilitatea sa produce-ti cod de zece ori mai rapid
decat cu uneltele pe care le folosim acum?
CB: Da, Acesta se numeste "Ruby on Rails" , si este de cel putin 10 ori mai rapida. Dar nu
am avut nici un succes cu propunerile domnilor. Nu a fost posibil nici macar sa le atarg atentia
asupra lor sa se uite la ele. Ei pur si simplu nu au avut incredere in adoptarea a ceva nou in mediul
lor de dezvoltare la acest moment.
Seful: CB, Trebuie neaparat sa rezolv aceasta situatie cu aplicatia pana maine dimineata. Daca ma
puteti ajuta atunci puteti folosi orice mediu de programare doriti. Numai dati-mi o aplicatie de web
bazata pe getionare de baze de date care arata si se comporta precum cea pe care seful meu a

vazut-o deja. Stiu ca va cer foarte mult. Probabil va rog sa lucrati pana tarziu in noapte. Maine
dimineata am mare nevoie sa fac impresie cu ea. Va spun ceva: Daca sunte-ti de acord sa face-ti o
buna impresie, voi da un telefon si sa incer sa vad daca pot sparge gheata pentru voi ca aceast
mediu de dezvoltare sa fie aprobat de conducere pentru voi in viitor.
CB: (vazand o oportunitate...) Sa va spun ceva sefule. E aproape ora pranzului. Daca ne aduce-ti
niste pitza, si si imi da-ti posibilitatea sa va arat cum Rails ne poate face productivi, cred ca putem
sa iti rezolvam problema pana se sfarseste timpul pranzului.
Seful: Imposibil, fugi-ti de aici! Pana timpul pranzului se sfarseste? Sunte-ti mari, CB.
CB: Nu sefule. Dumneavoastra aduce-ti pitzza si eu voi instala Rails. Persoanele de supraveghere
nu ma vor lasa sa downloadez Rails prin firewall (scutul de protectie) asa ca am adus un Cd azi
dimineata. Voi fi gata cand te vei intoarce inapoi.
Seful: Esti in stare sa instalezi si sa pui in functiune un mediu de dezvoltare pana ma intorc? Si
apoi, in timp ce mancam, esti in stare sa reproduci o aplicatie la care consultantul meu a muncit ...
ahh, nu conteaza. Ma duc. CB, nu te simti jicnit dar, acest lucru este chiar foarte greu de crezut.
Sper sa si ai dreptate.
Deci povestea incepe . Seful merge sa cumpere pitza si noi trebuie sa instalam Rails in mare viteza.

Instalare si configurarea Rails


In versiunea originala a acestui indrumar Curt Hibbs ( http://www.oreillynet.com/pub/au/2109 ) a
aratat cum se instaleaza si se configureaza Rails.
Pentru Windows, folositi

Instant Rails.

http://instantrails.rubyforge.org/wiki/wiki.pl

Iata mai jos cateva imagini semnificative asupra felului si modului de operare si lucru cu Rails:

Pentru

Mac OS X, folositi Locomotive. http://locomotive.raaum.org/

Pentru

Linux, folositi Rails LiveCD http://www.railslivecd.org/

Oricare dintre acestea va va putea ajuta sa fiti gata sa demarati dezvoltarea primelor aplicatii
Rails intr-un timp mai mic decat se poate livra o pittza.
Pizza Aici!

Seful: In regula, CB. Iata pitza. Acum stiu ca am fost de acord sa va las sa-mi prezenta-ti noul
utilitar faimos, dar nu am nevoie sa inteleg in detaliu "cum functioneaza?", deci l-am adus pe
Paul cu mine deasemeni. Nu-mi pasa daca voi amandoi intrati in amanunte mai mult daca nu
va pasa sa-l tratati ca un aspect auxiliar. Este in regula?
CB: Desigur, sefule. Buna Paul. Permite-mi sa iti ofer ceva de mancare si vom incepe
imediat! Mi-ai spus ca ai vrut ca aceasta aplicatie sa arate ca aplicatia la care tot voi ati lucrat
de la o vreme incoace. Dar, ai spus ca aplicatia este nefunctionala acum. Ce model de start
aveti pentru mine de la care sa imi incep lucrul?

Seful: Am gasit aceasta poza a imaginii principale afisate de aplicatie (Figura 1) pe biroul
consultantului.

Figura 1. Scopul final!


In principiu, aplicatia trebuie sa faca 3 lucruri:

Sa afiseze o lista de retete.


Sa creeze noi retete si sa editeze retetele existente.
Sa aloce o reteta la o categorie (ca de exemplu "desert" sau "supa").

Iata o insemnare pe care am gasit-o pe birou cu detaliile asupra modului cum aplicatia
functioneaza.
Caracteristicile functionale cerute

Titlu - La fel pentru toate paginile.


Antetul - La fel pentru toate paginile.
Tabel
o Reteta - Accesarea link-ului (legaturii) ne va conduce la o pagina care prezinta
o versiune needitabila a retetei. Pagina are legaturi pentru salvarea si editarea
retetei si pentru intoarcerea la pagina de listare.
o (sterge) - Accesarea acestei legaturi permite stergerea retetei din baza de date si
din pagina.
o Categorie - Accesarea acestei legaturi determina pagina sa fie reimprospatata si
reincarcata numai cu retetele din acea categorie inclusa.
o Data - Data trebuie alocata de catre sistem cand reteta este creeata sau editata.
Nota de subsol - Va apare pe toate paginile. OBSERVATIE: La Paginile De Categorie,
legatura din stanga va fi "Creeaza o noua categorie". Aceasta ar trebui sa se comporte

similar cu legatura "Creeaza o noua reteta". Restul notei de subsol este acelasi in toate
paginile.
o Creeaza o noua reteta - accesand aceasta legatura ne conduce la o forma de
intrare la numele recipientului, descriere, si instructiuni, si la selectia unei
categorii la care sa alocam o reteta.
o Afiseaza toate retetele- Accesarea acestei legaturi afiseaza toate retetele.
aceasta este folosita pentru a restaura afisarea ecranului dupa ce lista a fost
filtrata prin accesarea uneia din Legaturile De Categorie
o Afiseaza toate categoriile- Accesarea acestei legaturi ne conduce la
vizualizarea unei liste pe pagina pentru editarea sau stergerea intrarilor
existente in Categorie (Nota de subsol are legatura "Creeaza o noua
categorie").
Aste-i tot ce avem de facut.
Haide sa scriem codul!

CB: In regula, atunci. Hai sa-i dam drumul! Unul din lucrurile pe care Rails in mod real le
activeaza, Sefule, este o abordare iterativa si incrementala a dezvoltarii. Dupa cum veti vedea
de indata, Rails furnizeaza atat de mult pentru atat de putin efort incat este greu sa nu intrii in
acel ritm. In general, noi parcurgem aceeasi pasi de fiecare data cand dezvoltam o aplicatie
Rails.
1. Generam o aplicatie web de Rails-uri goale.
2. Ne decidem daca sa folosim numele de baza de date prestabilita pe care Rails il alege
sau sa ii spunem lui Rails ce baza de date dorim ca aplicatia sa foloseasca.
3. Daca nu exista deja, creeaza o baza de date pe care aplicatia noastra sa o foloseasca.
4. Decideti-va asupra carei specificatii sa se lucreze.
5. Daca ele nu exista, creeaza tabelele pe care aplicatia noastra va trebui sa le foloseasca
pentru producerea acestei specificatii
6. Genereaza o baza de cod pentru folosirea in tabel(e)
7. Corecteaza si reanalizeaza codul pentru a gasi eventualele erori si greseli.
8. Repeta pasii 4 la 7 pana la finalizare (este gata).
Acestia sunt pasii pe care urmeaza sa ii prezint.
Genereaza o aplicatie Rails goala

CB: Rails este un mediu de programare pentru dezvoltarea aplicatiilor. Aceasta presupune
printre altele ca fiecare aplicatie Rails sa aiba aceeasi structura de baza. Rails face acesta
conventie usor de urmarit prin generarea acelei structuri pentru noi cand ii spunem ca dorim
sa construim o noua aplicatie. Tot ce avem de facut este ...
Deschide o fereastra Prompt de Comanda si navigheaza unde doresti sa pui aplicatia. Aceast
loc este numit directorul Radacina a Rails. Numele sau va varia depinzand de ce sistem de
operare folosim (printre alte lucruri), dar numele si structura directoarelor va fi aceeasi. Deci
de acum inainte, caile despre care vom vorbi vor presupune portiunea de Radacina a Rails
(Rails Root).
Deci cum doriti sa numim aceasta aplicatie?

Seful: Noi am numit-o pe prima cookbook app.


CB: In regula. Hai sa o numim cookbook2.
Pentru a creea o aplicatie goala, noi trebuie sa executam comanda:
rails cookbook2

Rails creaza un subdirector cookbook2 (sub directorul Rails Root ) care contine un arbore
complet de foldere si fisiere pentru o aplicatie goala Rails (Figura 2).

Figura 2. Rails lucrand creeaza directorul noii aplicatii


Paul: Spune-mi mai mult despre structura directorului, CB. Sunt o gramada de directoare.
Urmeaza ca noi sa scriem cod ce trebuie pus in toate?
CB: Rails va pune codul in cele mai multe dintre ele, si mai ales in subdirectoarele aplicatiei
noastre. aplicatiile Rails folosesc paradigma Model-Afisare-Controler (Model-ViewController) pentru a organiza codul sursa al aplicatiei.

Sub-Directorul de controlere de aplicatie (app/controllers) este locul unde Rails se uita


sa gaseasca clasele controlerului. Un controler gestioneaza si manipuleaza o cerinta
web din partea unui user.
Sub-Directorul de afisaj de aplicatie (app/views) mentine sabloanele de afisare pentru
a le completa cu date de catre aplicatia noastra, converteste in HTML, si se reintoarce
la browser-ul utilizatorului (user-ului).
Sub-Directorul de modele de aplicatie (app/models) stocheaza clasele pentru acel
model si il actualizeaza cu datele stocate in baza de date a aplicatiei noastre. In multe
medii de programare (frameworks), aceasta parte a aplicatiei poate creste enorm de
mult si in dezordine, plictisitoare, tracasanta, si supusa la erori. Rails o realizeaza insa
intr-un mod uluitor de simplu!
Sub-Directorul de ajutor pentru aplicatie (app/helpers) stocheaza orice clasa de ajutor
(help) folosita pentru asistenta modelului, vizualizare si controlul claselor. aceasta
ajuta pentru a mentine modelul, a vizualiza, a avea un cod de controler redus, orientat
si neamestecat (in ordine).

Este important sa ne amintim ca aplicatia Rails este o aplicatie, ci nu un set aproximativ in cea
mai mare masura de pagini statice cu un pic de script adaugat. Aplicatiile Rails genereaza
paginile de web pe care le servesc. Deci este important sa intelegem cum functioneaza
controlerele in Rails si cum se cartografiaza in (si executa) metodele controlerului.
Clasele controlerului gestioneaza cerintele de apel web.. URL-ul cerintei de apel a
vizitatorului este cartografiat catre o clasa de controler si o metoda in clasa; ci nu catre o
pagina de web statica. Cand un vizitator incepe un ciclu cerere apel-raspuns prin introducerea
unui URL pentru aplicatia Rails in browserul acesteia, metoda controlerului de aplicatie este
invocata , in mod tipic primeste sau salveaza ceva date folosind modelele de aplicatie, si apoi
foloseste afisarea aplicatiei pentru a produce HTML pentru ca il trimeata inapoi in browserul
vizitatorului.
Pe langa fisierele din subdirectoarele aplicatiei, se afla alte doua fisiere in alte directoare care
deasemeni se vor edita sau creea. Vom vorbi despre acestea pe scurt, dar cea mai mare parte a
muncii nostre va fi creearea si editarea fisierelor din subdirectoarele aplicatiei.
Decide-te... sau spune-i lui Rails ce fel de baza de date va folosi aplicatia ta

CB: Acum pentru ca am construit o aplicatie Rails goala, avem nevoie sa o informam asupra
ce fel de tip de baza de date sa folosesca. Conventia Rails este ca numele bazei de date ce il
vom folosi in timpul dezvoltarii este numele aplicatiei (cookbook2, in acest caz) concatenat
cu _development (_dezvoltare). Cred ca aceasta va fi multumitor pentru noi.
Vom numi baza noastra de date cookbook2_development. Desi, am lasat parola pentru
dezvoltarea bazei de date necompletata (goala). Aceasta este conventia ce o foloseste Rails
cand genereaza fisierul de configuratie pentru baza de date. Daca am fi setat baza de date de
dezvoltare sa ceara o parola, am fi avut nevoie sa ii spunem lui Rails ce parola sa foloseasca
pentru a o accesa. Pentru a schimba atat numele bazei de date pe care dorim sa o folosim sau
parola folosita pentru accesarea ei, editati fisierul ..\cookbook2\config\database.yml.
Schimbarile pe care trebuie sa le facem sunt aproximativ evidente cand ne uitam in fisier.
Chiar si pentru tine, sefule (spune el facandu-i sefului cu ochiul). Pentru ca noi suntem in
regula cu folosirea conventiilor Rails, nu avem nevoie sa facem chiar si un efort foarte mic de
configurare.

Daca nu exista, creeaza baza de date pe care aplicatia nostra o va folosi

CB: Deci acum trebuie sa creem baza de date cookbook2_development. Nu stiu ce ai auzit
despre ce ti-am povestit Sefule, dar vreau sa fiu sigur ca stii ca nu oblig Rails sa inlocuiasca
utilitarele si aplicatiile sotware ale noastre existente. Partea dulce a Rails este construirea
aplicatiilor web conduse de baze de date. Nu sunt pentru a-i permite prajitorului de paine sa
dialogheze cu ceasca de cafea. Sunt platforme mai bune decat Rails pentru acesta. D fapt ...
Paul: Poate ca nu ar trebui sa mergem atat de departe acum, CB.
CB: Ai dreptate, Paul. Scuze pentru aceasta.
Aplicatia nostra Rails are nevoie de o baza de date. Am fost sigur ca motorul MySQL ruleaza.
In fereastra de comanda l-am deshis deja acolo. El se va loga ca user radacina (root user)
$ mysql -u root -p

Deoarece nu am setat o parola pentru aceasta aplicatie o sa apas tasta <Enter> la promptul de
parola.
Si apoi voi creea baza de date:
create database cookbook2_development;

(NOTA: Punctul si virgula de la sfarsit sunt obligatorii)


Deoarece lucrez in Windows, am nevoie deasemeni de a permite acesul la baza de date a unui
user numit ODBC. Daca nu, voi obtine o eroare de la MySQL cand incerc sa-l accesez de la
fereastra de comanda. Pentru a permite accesul, introduc:
grant all on cookbook2_development.* to 'ODBC'@'localhost';

NOTA: Daca nu lucrati intr-un mediu de dezvoltare windows (si in anumite cazuri, chiar daca
lucrati) aceasta permisiune poate sa nu fie necesara. In general, permitand drepturi nelimitate
pentru o baza dumneavostra de date la un user generic este ceva ce nu face-ti in mod usual.
Am inclus acest lucru aici pentru a ajuta asigurarea faptului ca nu vei intalni o problema usor
de evitat in timp ce urmariti acest tutorial (indrumar).
Asta este. Noi Suntem gata cu MySQL deci eu voi ....
Exit

(iesire)

...si ma voi intoarce la sistemul de operare (Figura 3).

Figura 3. CB creeaza o baza de date MySQLpentru aplicatia saRails pentru Windows.


Decide-te asupra carei specificatii (caractersitici) sa lucrezi

CB: IN REGULA, Sefule. Aceasta imagine de pe ecarn pe care mi-ai prezentat-o arata ca noi
putem creea , citi, improspata, si sterge retete. Nota consultantului pe care mi-ai dat-o spune
ca noi putem face aceleasi lucruri cu categoriile, si ca fiecare reteta este alocata la o singura
categorie. In ansamblu totul pare foarte clar. Unde credeti ca ar trebui sa incepem? (CB
intreaba cu putin ranjet propriuTragandu-lpe sfoara pe sef este asa amuzant)?
Seful: Bine, CB (spuse el putin cam binevoitor), Presupun ca mai bine sa incepem cu creerea
unei retete, corect? Apoi continuam cu citirea ei. Apoi editarea ei apoi stergerea ei Apoi
trebuie sa facem la fel pentru categorii, si apoi trebuie sa le asamblam si sa le interelationam
impreuna. In final ne vom baga in codare reala. Nu-i asa ca acesta este modul in care in mod
obisnuit noi realizam acest lucruri?
CB: Da. Acesta este modul obisnuit de a face aceste lucruri, Sefule. Mereu asa si tot asa . Si
acesta este si punctul de vedere in Rails. Urmeaza sa facem aceleasi lucruri de fiecare data
cand dezvoltam o aplicatie bazata pe o baza de date. Haide-ti sa automatizam acest lucru si sa
trecem la treaba. Rails presupune ca noi urmeaza ca noi sa avem nevoie sa creem, citim
improspatam si stergem orice data despre care ii spunem ca urmeaza sa o folosim. Odata ce
avem tabelele bazelor de date pentru aceasta in vederea lucrului cu ele, Rails va genera tot
codul de baza de care avem nevoie. Aceasta inseamna ca noi putem sa ne permitem sa
avansam cu pasi mai rapizi decat o facem in mod uzual. Aici este locul unde productivitatea
inzecita isi face aparitia.
Aceasta aplicatie este in general foarte simpla pentru Rails. De fapt, este chiar in punctul cel
mai proeminent si dulce al lui Rails, deci hade-ti sa urmam un salt rapid.
Creeaza tabelele pe care aplicatia dumneavoastra le va necesita pentru a produce aceste specificatii (caracteristici)

CB: Este aparent ca vom avea nevoie de un tabel pentru retete si un altul pentru categorii.
Relatia dintre cele doua este 1-la-multe categorii pentru retete. Aceasta inseamna ca avem
nevoie sa includem un camp cheie strain in tabelul de retete: recipes.
O sa deschid editorul de text favorit si voi scrie cateva linii de script SQL, pentru a le creea.

drop table if exists recipes;


drop table if exists categories;
create table categories (
id
int
name
varchar(100)
primary key(id)
) engine=InnoDB;

not null auto_increment,


not null default '',

create table recipes (


id
int
not null auto_increment,
category_id
int
not null,
title
varchar(100)
not null default '',
description
varchar(255)
null,
date
date
null,
instructions
text
null,
constraint fk_recipes_categories foreign key (category_id) references
categories(id),
primary key(id)
) engine=InnoDB;

CB: Hei Paul, Iti amintesti ca am spus ca sunt doua fisiere in afara directorului de aplicatie in
care lucram? Scriptul SQL pentru a seta tabelele pe care aplicatia le foloseste este unul din
ele. Deci Sefule acum am salvat fisierul in ..\cookbook2\db\create.sql, si suntem gata sa creem
tabelele.
In fereastra promptului de comanda pe care o tin deschisa, ma mut in directorul cookbook2.
Dupa ce ma asigur ca sunt in directorul cookbook2, introduc:
mysql cookbook2_development <db\create.sql

MySQL executa scriptul si se intoarce la linia de comanda fara sa ne spuna nimic. Aceasta
inseamna ca totul a decurs in regula. Baza noastra de date contine doua tabele goale: recipes
(retete) si categories (categorii).
Paul: CB, acel script seamana cu un script MySQL. aceasta poate fi o problema pentru
persoanele de la controlul tehnic de calitate.
CB: Stiu. O alta parte secundara a scripturilor SQL este pierderea datelor cand va decideti ca
aveti nevoie de un camp in tabel. Partea buna cu scripturile este ele sunt foarte usore. De
aceea eu folosesc unul aici Sefule.
Din fericire Rails ne da o unealta numita migrations (migrari). Este putin cam mult sa intram
in amanunte despre ea acum, dar migrarile ne permit sa efectuam mult din munca noastra pe
modele in mod incremental fara sa pierdem datele de fiecare data cand facem o schimbare.
Poate vom avea o sansa sa vorbim mai mult despre asta mai tarziu.
Genereaza o baza de cod pentru a fi folosita in tabel(e)

CB: Acum ca avem tabelele la care Rails se poate uita, le vom cere sa genereze aplicatia
noastra de baza. In jargonul Rails aceasta, se numeste scaffolding (structurare). In linia
promptului de comanda, aveti grija ca suntem inca in subdirectorul cookbook2, voi introduce:
ruby script\generate scaffold recipe recipe

Apoi spune-i Rails sa genereze structurarea: modelul de baza, controllerul, si afisarea


fisierelor pentru partea de aplicatie care se va folosi in tabelul de retete. Pute-ti vedea ca Rails
genereaza chiar cateva fisiere (Figura 4). In linia de comanda ce tocmai am introdus-o i-am
spus Rails despre doua fisiere in particular: modelul (primul argument) si controlerul (al
doilea/ultimul argument). Rails a numit fisierul de model recipe.rb si la plasat in subdirectorul ..\cookbook2\app\models\. Intr-un mod asemanator acesta a numit fisierul de
controler recipe_controller.rb si la plasat in sub-directorul ..\cookbook2\app\controllers\.

Figura 4. Generarea retetei de cod de structura (scaffolding code)


Acum vom proceda asemanator pentru categorii. din nou in fereastra de comanda, vom
introduce:
ruby script\generate scaffold category category

Aceasta ii spune lui Rails sa genereze un model de baza, controlerul, si fisierele de afisare
(Figura 5) pentru partea din aplicatia noastra care va folosi un tabel de Categorii. Ca si mai
inainte, Rails va denumi fisierul de model si il va plasa in
..\cookbook2\app\models\category.rb si va numi fisierul de controler si il va plasa in
..\cookbook2\app\controllers\category_controller.rb.

Figura 5. Generarea codului de structurarepe categorii ( the category scaffolding code)


CB: In regula Sefule, Boss. Tot ce am facut pana la acest moment a fost foarte scurt si fara
batai de cap, dar nu in particular pasionant. Aici este punctul cand acest lucru se schimba.
Inainte de a merge mai departe, hai sa aruncam o privire la exact ce am facut. am introdus un
numar total de 8 linii de comanda: cinci MySQL comenzisi trei linii Rails. Am creeat un script
SQL cu 17 linii care nu sunt goale. Aceasta nu este ceea ce am numit codare reala inca, dar
dupa cum urmeaza sa vedeti ... ei bine ... tineti-va bine!
Imbunatatiri rapide

CB: Urmeaza sa folosin serverul de web numit Mongrel pentru a va servi aplicatia. Pentru a il
porni, in sub-directorul cookbook2 din linia de comanda, voi introduce:
mongrel_rails start

Cand Mongrel a terminat pornirea, este gata sa va serveasca aplicatia.

Figura 6. Pornirea serverului de web


CB: Sunte-ti gata?
Seful: Gata pentru ce? Tu tocmai mi-ai adus aminte ca nu ai scris inca nici un pic de cod.

CB: Este adevarat dar acest lucru nu inseamna ca nu am fost productiv. Aici; ... ia tastatura.
Acum deschide o fereastra de browser si puncteaz-o la http://localhost:3000/category (Figura
7).
Paul: Nu am auzit niciodata de Mongrel, CB. Chiar trebuie ca aplicatiile Rails sa il
foloseasca?
CB: Deloc, Paul. Mongrel este un server de web foarte usor, si foarte prietenos cu Rails. Este
renumit pentru deservirea aplicatiei noastre local in timpul dezvoltarii, si este larg folosit in
medii de productie, deasemeni. Totusi, nu este un lucru care trebuie folosit obligatoriu. Sunt
numeroase alternative. Putem intra in detalii despre acest lucru mai tarziu.

Figura 7. Primela noastra aplicatie Rails!


Accesati legatura (Figura 8).

Figura 8.Pagina de intrare la categoria noua


Introduce-ti un nume de categorie si accesati butonul "Create " ("Creeaza") (Figura 9).

NOTA: Cititorul tipic, incredibil de destept si viclean O'Reilly tocmai a observat ca CB nu a


spus "Introduce-ti o reteta si accesati butonul 'Create' " aici. "De ce aceastat?",probabil a-ti
fi tentat sa intrebati.Nu va functiona inca. Amintiti-va: noi nu am scris nici un cod pana
acum. Noi nu vom scrie mult cod dar, avem nevoie de cateva linii de cod pentru a asambla
totul impreuna. Nu mult. Numai putin.

Figura 9. Noua categorie adaugata!


Seful: Acum nu numai ca este atractiv- este teribil! Ce poti sa imi spui despre retete?
CB: Scrie numai in browserul dvs adresa http://localhost:3000/recipe (Figura 10).

Figura 10. Lista goala de retete


Accesati legatura (Figura 11).

Figura 11. Pagina de intrare in noua reteta


CB: Unde ti-e palaria, Sefule? Trebuie sa iti fi zburat! Ti-am spus sa ti-o tii bine!
Seful: Aceasta este uimitor, CB. Trebuie sa iti spun adevarul. Cand am fost de acord sa manac
o pizza cu tine, nu am avut chiar atata credinta ca tu intradevar vei fi in stare sa faci aceasta
aplicatie, sa porneasca si sa se termine, inainte ca masa de pranz sa fie gata. Incep sa am
impresia ca nu mai stimat.

CB: Si nu am scris inca nici macar o bucatica de cod! Probabil ca sunte-ti nerabdator sa o
faceti, dar inainte sa va apucati hai sa servim putina pizza 'Pentru ca stiti, cu Rails, putem sa
avem felia si sa mancam deasemeni!
Paul: Buna pizza. Multumesc, Sefule. Asculta, Stiu ca ne-ai intrebat sa vorbim despre
detaliile chestiunilor secundare, dar as muri sa vad ca codul generat de Rails ar produce asa
ceva. V-ar deranja daca l-as ruga pe CB sa isi rezerve cateva momente si sa ne prezinte acest
aspect?
Seful: De fapt , Paul, sunt destul de interesat in vizionarea acestui aspect eu insumi, CB, esti
dragut? Dar te rog prezinta pe scurt, OK?
CB: Nici o problema. ("E usor acum," CB ramane ranjind. "Nu vrei sa trag de maner.")
Haide sa ne aruncam ochii pe codul de controler pentru retete (Figura 12). Amintiti-va ca
Rails stocheaza codul controlerului din directorul controlere intr-un fisier cu numele pe care il
alege bazat pe argumentele ce noi le-am furnizat cand am generat structurarea (scaffolding).
In cazul nostru, i-am spus sa genereze un model si un controler; ambele numite recipe
(reteta). Controlerul este botezat recipe_controller.

Figura 12. Controleru nostru de recipient


Seful: acesta este chiar un cod foarte mic si inteleg marea majoritate din el. Vreau sa spun, ai
spus ca Rails urma sa genereze cod pentru creeare, citire, reinoire (update), si stergere. Vad o
metoda de creeare, si metode de reinoire si distrugere. Presupun ca metodele de afisaj si
listare sunt pentru citit, dar pentru ce sunt metodele pentru nou si editare? Ele nu par sa fac
prea mult.
CB: acesta este una dintre diferentele dintre o aplicatie reala de web si un site care poate avea
chiar multe pagini statice cu ceva script in ele, Sefule. Intr-un site scriptat, probabil ca am pus

de mana cod HTML in forme pe care vizitatorul le foloseste pentru a introduce date. Apoi am
codat metoda de creeare pe partea de server pentru a salva datele cand forma a fost trimisa.
Amintesteti ca Rails, genereaza paginile pe care le deserveste, deci urmeaza sa creeze o forma
HTML pentru noi. Metoda de NOU si EDITARE numai furnizeaza un obiect pentru ca forma
sa il foloseasca. Metodele de creeare si inoire salveaza obiectul in baza de date cand forma
este trimisa.
Seful: In regula. Cred ca inteleg bazele acum. Paul, esti de acord sa mergem mai departe
acum?
Paul: In regula, Sefule. Ma voi intalni cu CB mai tarziu pentru ca sa imi prezinte mai in
amanunt aceste aspecte.
CB: In regula, acum. Haide-ti sa ne intoarcem inapoi la problema. Probabil ca ati observat ca
nu exista nici o metoda de a atribui o categorie pe o pagina de recipient nou. acesta deoarece
i-am spus lui MySQL, ca fiecare reteta sa aiba o categorie, dar nu i-am spus lui Rails acelasi
lucru. Tot ce am nevoie sa fac este sa ii spun lui Rails cum cele doua sunt inrudite si sa adaug
doua linii in fisierul de afisare pentru pagina de reteta noua.
O sa-i spun lui Rails despre relatia dintre retete si categorii in modelele lor. In fisierul
cookbook2\app\models\category.rb (Figure 13), o sa-i spun lui Rails ca fiecare director va
avea mai multe recipiente alocate la el prin adaugarea unei linii.
has_many :recipes

Figura 13. Fisierul model de categorie


Apoi o sa-i spun lui Rails ca fiecare recipient este alocat la o singura categorie prin adaugarea
unei linii la modelul recipientului (cookbook2\app\models\recipe.rb, Figura 14).
belongs_to :category

Figura 14. Fisierul model de recipient


Acum Rails stie despre relatia intre cele doua modele.

Pentru a da vizitatorului abilitatea de a selecta o categorie, avem nevoie sa adaugam doua linii
la afisajul noii retete. acest fisier de afisare pentru metoda new (nou) in reteta (recipe)
controlerului este in subdirectorul de reteta sub afisari (views). Pentru a ajusta aceasta afisare
(view), voi deschide fisierul cookbook2\app\views\recipe\_form.rhtml (Figura 15).

Figura 15. Forma partiala generata de Rails


Paul: CB, am observat ca sunt o gramada de fisiere in acel director, si ca unul dintre ele este
new.html. Cum se face ca nu editezi acel fisier?
CB: Ai un ochi foarte atent, Paul. Rails genereaza fisierul de afisaj pentru fiecare metoda din
controler, dar unul dintre principiile de baza in ghidarea Rails este "Nu te repeta". Afisarile
Rails ne permit sa modularizam codul nostru de afisaj. Deoarece metoda new si metoda edit
lucreaza impreuna pe acelasi obiect, Rails o creeaza partial, o numeste _form.rhtml, si o
foloseste in afisarile new (nou) si edit (editare). O afisare (view) poate include multe partiale
deoarece noi dorim sa ne mentinem codul USCAT. vom efectua mai multa munca pe fisiere in
scurt timp.
CB: Pentru a adauga selectarea categoriei, avem nevoie de doua linii de cod
<p><label
for="recipe_category_id">Category</label><br/>
<%= select("recipe", "category_id", Category.find(:all).collect
{|c| [c.name, c.id] }) %></p>

Prima linie este un cod HTML pur. a doua linie este un cod Ruby. Rails vede portiunea <
% ... %> si stie ca ce este inauntru este un cod Ruby incapsulat (embedded) de care are
nevoie pentru a executa generarea codului HTML pe care trebuie sa-l trimita inapoi
browserului. Deoarece acesta are semnul =, Rails va genera codul HTML ce avem nevoie
pentru o eticheta de selectie (select tag). Daca nu ar fi avut semnul = semn, si vom vedea
cateva exemple de acest gen deasemeni, Rails ar fi executat codul dar nu ar fi generat nici un

cod HTML. E posibil sa fi observat ca noua pagina de retetalasa vizitatorul sa selecteze data,
dar cerintele spun ca sistemul trebuie sa aloce data. Cand sunt aici, urmeaza sa sterg liniile
care permit utilizatorului sa faca acest lucru. acum trebuie sa avem o forma partiala care arata
ca in Figura 16.

Figura 16. Forma partiala reinoita

CB: Acum trebuie sa avem sistemul alocand o data ori de cate ori cineva creeaza sau
reinoieste (update) o reteta. Aceasta necesita sa se intample in controlerul de reteta, deci voi
deschide cookbook2\app\controllers\recipe_controller.rb (Figura 17) si voi aduga o linie la
ambele metode create si update. (creeaza si reinoieste)
@recipe.date = Time.now

Figura 17. Preluarea alocarii datei de catre controler

Done!
CB: In regula, Sefule. Noi am adaugat 6 linii de cod. Este timpul sa ne verificam treaba. am
modificat fisierele model deci este nevoie sa repornesc serverul nostru de web: mongrel. din
motive de performanta, chiar si in modul de dezvoltare Rails numai citeste fisierele model ale
aplicatiei la pornire (startup). Ori de cate ori noi modificam un model Rails, trebuie sa
repornim serverul nostru de web. Pentru a opri Mongrel, in fereastra de comanda, Ctrl-C. apoi
il repornesc, introduc ...
mongrel_rails start

CB: In regula, Sefule. Esti gata sa faci onorurile? Indreapta browserul nostru catre
http://localhost:3000/recipe/new, si ...
Voil! Data a disparut si este o lista de selectie pentru Category (Categorie).
Paul: Am observat ca in controler, cea mai mare parte a referintelor au fost catre o variabila
numita @recipe. Aici in forma, desi, arata ca si cum ai referii acelasi obiect folosind o sintaxa
diferita.
CB: Ai dreptate, Paul. Textul text_field foloseste o sintaxa diferita, dar se refera exact la
acelasi obiect pe care controlerul il foloseste cu o variabila de instanta. Poate fi nitel cam
confundabil la inceput. Exista totusi o explicatie mult mai precisa, dar uite cum am gasit eu de
cuvinta sa o exprim direct cand am inceput. am folosit o variabila de instanta pentru a impinge
treburile catre user. Orice variabila de instanta pe care o creez in controlerul meu este
disponibila automat pentru afisajul ce il folosesc pentru generarea fisierului HTML pe care il
voi trimite inapoi catre browserul vizitatorului. Cand am nevoie sa obtin informatie de la
vizitator, ma voi intoarce inapoi la ceva cunoscut ca tabela hash de parametrii (params hash).
Aceasta este o structura de date care se construieste in browserul vizitatorului si este trimisa
inapoi cand acesta porneste un nou ciclu cerere-raspuns. Sintaxa text_field, de exemplu, de
fapt ma ajutat sa imi amintesc cum sa scot datele afara din forma. Daca am un text_field intr-o
forma ca de exemplu <%= text_field 'recipe,' 'description,' %> atunci il pot accesa
in controler cu @recipe.description = params[:recipe][:description], sau il pot
prezenta inapoi vizitatorului intr-un nou ciclu daca vreau ca prin folosirea @recipe =
Recipe.find(the_one_I_want) in controler, si apoi folosirea <%= @recipe.description
%> in afisare. Este mult mai mult de spus despre el decat atat, binenteles, dar ma ajutat sa
mentin explicatiile clare la inceput.

Figura 18. Pagina de creere a recipientului reinoita


Da-i inainte si creeaza o noua reteta , Sefule. Tocmai ne-ai servit cu o pizza deci probabil ca
acea reteta este proaspata in mintea ta ;-)

Figura 19. Prima noastra reteta!


CB: ai inceput sa fii impresionat?
Seful: Bine, desigur. Dar nu arata nimic ca originalul inca. Putem sa fixam aceasta problema
putin acum?
CB: Este foarte simplu! Obser numeroase lucruri care necesita atentie. Afisajul retetei are
nevoie de un hotar (border). Coloana de antet pentru titlu necesita o schimbare, si tabelul are
nevoie de o coloana pentru a afisa fiecare categorie a retetei. Lista consultantului de cerinte
spune ca prin accesarea categoriei retetei se va sorta lista in asa fel ca numai retetele din acea
categorie sunt prezentate. Aceasta inseamna ca noi avem nevoie de niste legaturi pentru
fiecare categorie de reteta. Imaginea luata de pe ecranul calculatorului arata deasemenea ca
instructiunile nu trebuie sa apara in listare. Cerintele spun ca obtiunea EDIT (EDITARE) va fi
disponibila dintr-o afisare needitabila pe care noi o vom obtine prin accesarea (clicking on)
numelui retetei. In final, imaginea de pe ecranul calculatorului arata ca legaturile (link-urile)
SHOW (ARATA) si DESTROY (DISTRUGE) pentru reteta au nevoie de putina rearanjare.
Seful: Aceasta pare sa necesite foarte multa munca!
CB: Foarte multa munca pe unele platforme. Fii atenta aici: Deschid fisierul
cookbook2\app\views\recipes\list.rhtml (Figura 20). In fond, ce face este citirea modelului
Retetei si creearea unui tabel cu o coloana pentru fiecare atribut, punand un antet de tabel
(table header) pe fiecare coloana cu numele atributului,si apoi creeind randuri in tabelul
Retetelor (Recipes table).

Figura 20. Vedere de ansamblu asupra listei cu reteta generata de Rails (Rails-generated
recipe list view)
CB: Urmeaza sa facem cateva schimbari oarecum majore aici. Trebuie sa o fac sa arate dupa
cum urmeaza:
<table border="1">
<tr>
<th width="60%"><em>Recipe</em</th>
<th width="20%"><em>Category</em></th>
<th width="20%"><em>Date</em</th>
</tr>
<% for recipe in @recipes %>
<tr>
<td><%= link_to %Q{#{recipe.title}}, :action => 'show', :id => recipe
%>
<%= link_to '(delete)', { :action => 'destroy', :id => recipe },
:confirm => 'Are you sure?', :post => true %></td>
<td><%= link_to %Q{#{recipe.category.name}},
{:action => 'list', :category_id => recipe.category.id}
%></td>
<td><%=h recipe.date %></td>
</tr>
<% end %>
</table>

CB: In Regula. Dupa socoteala mea, noi am adaugat deja sapte linii de cod. Ar fi mai bine sa
ne verificam treaba ;-) Sefule, esti dragut sa iti reimprospatezi pagina de web din browser
(dai un refresh in browser)?
CB: Ei, Paul. Iti amintesti ce ti-am spus depre variabilele de instanta in contrast cu
parametrii? Vezi cum folosim variabila de instanta @recipes in bucla for? Valoarea sa este

setata in controler, si acum noi o folosim in afisaj pentru a creea afisarea in pagina pe care o
trimitem inapoi catre vizitator.

Figura 21. Facand-o draguta


Seful: Se pare ca ne apropiem de ceea ce am dorit initial (Figura 21).
CB: In mod sigur suntem . Dar trebuie sa ne amintim sa testam verificand daca filtrarea
functioneaza cand dam click pe categoria retetei. Am introdus o singura categorie pana acum,
deci nu putem testa acest lucru inca. Cat timp suntem in modul afisaj de cod (view code), hai
sa terminam cu acesta parte.
Cerintele spun ca avem nevoie de o nota de subsol pe fiecare pagina care ne duce fie la lista
de retete sau la lista de categorii. Fereastra de titlu si antetul paginii au nevoie deasemeni sa
fie la fel pe fiecare pagina. Hai sa adaugam toate acestea acum.

Directorul cookbook2\app\views\layouts contine 2 fisiere: category.rhtml si recipe.rhtml. Voi


sterge unul (si numai unul) si il voi redenumi pe celalalt: application.rhtml. Acum il voi
deschide pe application.rhtml (Figura 22).

Figura 22. Lucrand cu fisierul schita (macheta) a aplicatiei


CB: Prima data voi schimba titlul ferestrei...

<title>Online Cookbook</title>

Si voi adauga un antet pentru pagina...


<h1>Online Cookbook</h1>

Rails aplica ce gaseste aici pentru toate paginile pe care aplicatia le deserveste. Deci prin
adaugarea a numai cateva linii voi adauga o notita de subsol pe fiecare pagina
<p><% if params[:controller] == 'recipe' %>
<%= link_to "Create new recipe", :controller => "recipe", :action =>
"new" %>
<% else %>
<%= link_to "Create new category", :controller => "category", :action
=> "new" %>
<% end %>
<%= link_to "Show all recipes", :controller => "recipe", :action =>
"list" %>
<%= link_to "Show all categories", :controller => "category", :action =>
"list" %></p>

Ceea ce ne da Figura 23

Figura 23. Fisierul schita al aplicatiei modificat


Salvam asta. In regula, Sefule. Am schimbat continutul liniei <title> (titlu) si, prin
abordarea mea generoasa (numarand deasemeni si liniile schimbate), am adugat sapte linii de
cod. Esti gata sa verifici acest program din nou?

Seful: Sigur, CB. Reimprospateaza-ne browserul si ... (Figura 24).

Figura 24. Rezultatele in browser pentru nivelul de aplicatie


Seful: Sa fiu al naibii !
Paul: Mai devreme ati folosit afisari si partiale pentru a extrage efectele vizuale, CB. Acum
folosesti schite. Poti sa-mi explici nitel despre ele?
CB: Desigur, Paul. Schitele (Layouts) sunt un mecanism pe care Rails il realizaza pentru a-i fi
mai usor sa aplice principul DRY la codul nostru de afisaj. Cand generam structurarea
(scaffolding) pentru perechea model/controler, Rails presupune ca noi probabil dorim cateva
carcateristici comune in aspectul si prezentarea paginilor afisate metodele controlerului.
Schitele ne permit sa ne invelim afisarile. Prin sablon, cand Rails are nevoie sa genereze o
pagina, se uita dupa un fisier de afisare cu acelasi nume ca si metoda. Apoi cauta instructiuni
ulterioare in fisierul schita (layout file) cu acelasi nume ca si controlerul. Daca fisierul schita
nu exista, atunci Rails se uita dupa un fisier numit application.rhtml. Folosind o combinatie
de partiale, afisaje si schite (partials, views, and layouts), Rails ne da un mod usor de a
controla ce va oferi drept prezentare vizitatorului la nivelul metodei, la nivelul controlerului,
si la nivelul aplicatiei.
CB: Intocmai. Dar aminteste-ti ca nu am reusit sa testam filtrarea daca intradevar isi
realizeaza scopul. Acum pentru ca am ajuns acolo de aici, hai sa mergem si sa adaugam o
categorie pentru a ne permite sa putem filtra ulterior. Apasa (Click) pe legatura (likul) Show
all categories (Afiseaza-ne toate categoriile) (Figura 25).

Figura 25. Listarea initiala a categoriei


CB: Avem de facut putina curatenie, acelasi lucru pe care l-am facut deja pentru retete. Dar
inainte sa facem asta, hai sa verificam comportamentul. Hai sa vedem ce se intampla cand
apas (click) pe legatura (link) ca sa adaug o categorie noua. Fiecare legatura (link) va lucra
bine. (Figura 26)

Figura 26.Pagina de creeare a noii categorii


Avem deasemenea nevoie de aceeasi curatare aici. Hai sa fim la obiect, si sa continuam prin
adaugarea unei noi categorii numita "beverages" (bauturi alcolice) (Figura 27).

Figura 27. Noua categorie adaugata la lista


In regula. Trasatura categorie noua functioneaza, deci hai sa stergem felul cum arata. Noi nu
avem nici o imagine de pe ecran cu faptul cum listarea categoriei ar trebui sa arate, deci
urmeaza numai sa presupun ca e similara cu listarea Retetei (Recipe). Hai sa continuam si sa o
facem pe aceasta sa se schimbe.
Voi edita fisierul cookbook2\app\views\category\list.rhtml. Acesta arata foarte asemanator cu
afisajul listei pentru retete (the list view for recipes). Am de gand sa fac in mare aceleasi
schimbari pe care le-am facut inainte.
Sterge linia de antet (heading line).
Adauga atributul de granita sau margine la eticheta tabelului (table tag).
<table border="1">

De aceasta data voi lasa in pace antetele tabelului (table headings) deoarece este doar unul
singur iar acesta pare in ordine. Aceasta inseamna ca trebuie numai sa inlocuiesc codul
generat de liniile tabelului.
<td><%= link_to %Q{#{category.send(column.name)}}, :action => 'show', :id
=> category %>

<%= link_to '(delete)', { :action => 'destroy', :id => category },


:confirm => 'Are you sure?', :post => true %></td>

Apoi sa sterg liniile sub eticheta </table>. Acum pentru ca suntem gata cu aceasta... (Figura
28).

Figura 28. Afisajul fisierului listei de categorie reactualizata si reimprospatata


Voi merge inainte si il voi salva
Seful: Cred ca am inceput sa inteleg asta, CB (spune el zambitor) Am adaugat doua linii in
plus. E mai bine sa ne verificam munca din nou. Corect?
CB: Separe ca exista ceva speranta pentru tine, Sefule (ranjind deasemenea). De ce nu ne
faci onoarea?
Reinoieste imaginea din browser (Refresh our browser) si... (Figura 29).

Figura 29. Listarea categoriilor reimprospatata in browser.


Seful: Vad intradevar ce ai vrut sa spui cand ai zis "Unul din lucrurile pe care Rails le
faciliteaza este abordarea incrementala si iterativa a dezvoltarii de aplicatie" Vad unde intr-un
proiect normal tu nu poti merge foarte departe inainte de a avea un raspuns si dialog din
partea partea clientului.Vei apuca pe o cale gresita foarte repede daca nu mentii un dialog cu
clientii si sa le ceri si parerea lor.
CB: Poftim.

Tocmai mi-am amintit ca fisierele new.rhtml si edit.rhtml de sub subdirectoarele


views\categories si views\recipes necesita sa aiba liniile de antet <h1> (heading lines) sterse
deasemenea. Voi continua si voi face acest lucru foarte repede.
Spune-mi, Sefule. Ma dor intradevar degetele de la toata aceasta dactilografiere ;-) Acum
pentru ca avem mai mult decat o singura categorie, avem nevoie sa fim siguri ca selectia
categoriei functioneaza cand adaugam sau reinoim o reteta. Ai crezut ca poti sa faci tu singur
asta pentru noi? Acceseaza (Click) pe legatura Arata toate retetele (Show all recipes link).
Apoi acceseaza (click) pe legatura Creeaza o noua legatura catre noua reteta(Create new
recipe link). Introduce-ti o noua rereta (Enter a new recipe) si aloca aceasta reteta la categoria
bauturi alcolice (beverages category). Avem nevoie de cel putin un fel principal si o bautura
alcolica (Figura 30).

Figura 30. Listarea retetelor cu categorii diferite


CB: Pare ca tot ce mai avem de facut este filtrarea cand accesam o categorie de retete. Am
setat legatura sa foloseasca filtrarea cand am folosit afisajul listarii retetelor, dar nu am pus
inca comportamentul in acest loc inca. Acesta merge in controlerul de reteta, deci am deschis
cookbook2\app\controllers\recipe.rb file si am inlocuit continutul metodei de listare (list
method) cu urmatorul cod:
if params[:category_id].nil?
@recipes = Recipe.find(:all)
else
@recipes = Recipe.find(:all,
:conditions => ["category_id = ?",
params[:category_id]])
params[:category_id] = nil
end

Odata ce voi fi gata, o sa slvez fisierul. In regula, Sefule. Am mai adaugat alte 6 linii de cod.
Stii ce inseamna asta;-)

Seful: Cred ca incep sa intru in ritm ;-) Hai sa vedem. Improspateaza pagina in browser, apoi
accseaza (click) pe legatura la bauturi alcolice (beverages link) (Figure 31).

Figura 31. Lista retetelor filtrata pentru o singura categorie


CB: Simplu si la obiect! Perfect, Sefule. Acum acceseaza legatura Arata toate retetele: Show
all recipes link (Figura 32).

Figura 32. Suntem aproape gata done!


CB: Am facut-o, Sefule!!! Daca nu sunt sigur, cred ca suntem gata!
Seful: Arata in mod sigur precum am dorit!

CB: Numai ca sa te asiguri deja, de ce sa nu ii dai o rulare de la cap la coada. Idee: Acceseaza
( Click) pe legatura Arata toate categoriile (Show all categories link), apoi acceseaza (click)
legatura (delete) link (stergere) in categoria Bauturi alcolice ( Beverages category).
Seful: Ei! Asta nu e corect! (Figura 33)

Figure 33. Un mesaj de eroare al Rails


CB: Intocmai. Iti amintesti prima linie de cod Rails pe acre am introdus-o? A fost in categoria
din fiserul category.rb, adica din fisierul model de categorie.
has_many :recipes

Mesajul de eroare ne spune ca tocmai am incercat sa stergemo inregistrare care are copii.
Rails ne-a oprit din stergerea accidentala a unui manunchi de retete. Sunt o gramada fe feluri
in care noi putem sa abordam acest aspect dar cerintele nu spun nimic despre aceasta situatie
si mai ales cum sa ne descurcam in acest caz. Aceasta este intradevar o decizie pe care clientul
trebuie sa o ia singur. Momentan o sa o fixez
In asa fel incat aplicatia sa nu esueze (crash). Apoi tu poti sa iti intrebi seful maine asupra
modului in care el vrea ca ea sa lucreze. Voi adauga niste cod pentru a ignora cerinta asupra
faptului daca exista inregistrari de copii (child records). Codul merge in metoda distrugere
(destroy method) din categoria fisierului controlerului
(cookbook2\app\controllers\category_controller.rb). La inceput voi voi interoga toate retetele
care au fost alocate categoriei pe care urmeaza sa o sterg.
recipes = Recipe.find(:all, :conditions => ["category_id = ?",
params[:id]])

Apoi o sa invelesc stergerea inregistrarii (record deletion) intr-o instructiune if (daca) care nu
va permite ca stergerea sa se intample daca Rails a gasit vreo inregistrare.

if recipes.empty?
Category.find(params[:id]).destroy
end

Si suntem gata. Deci acum avem si fisierul de controler... (Figura 34).

Figura 34. Metoda modificata de distrugere pentru a repara eroerea


Seful: Si am adaugat inca doua linii! E timpul sa ne controlam munca din nou ;-)
Reimprospateaza pagina din browser (cu Refresh). Mergi inapoi la listarea retetelor si sterge
reteta pentru ceai de gheata (ice tea recipe). Acum mergi inapoi la listarea de categorii si
sterge categoria bauturilor alcolice(delete the beverages category). (Figura 35).

Figura 35. Houston, Noi avem o lansare!


Seful: Este gata!!!
CB: Ce?!?!?!? Asta nu poate fi corect! Pitza nici nu sa racit inca ;-)
Serios, acum, Sefule, ai dreptate. Noi tocmai am terminat aplicatia noastra web bazata
(condusa de) pe baze de date, complet functionala folosind Rails. Cat timp a luat? 30 sau 40
de minute? Taste apasate? Dupa socoteala mea am numarat urmatoarele:
MySQL commands: 5
SQL script:
17 lines
Rails commands: 3

Rails code:

31 lines

31 linii de cod? Nici un fisier de configuratie? Un singur script SQL si 8 linii de intrare in
linia de comanda? Si suntem gata?
Seful: Ai dreptate. Aceasta este nemaipomenit. Spuneai ca ai nevoie de ajutor in privinta
persoanelor de la CTC (Ops guys)? Sunt alaturi de tine. Am de gand sa-i spun sefului meu
despre asta maine dimineata. Aveti cateva cuvinte pe care mi-ati sugera sa le folosesc?
CB: Ai intuit corect. Spune-i asta.
Rails este urmtoarea generatie in programarea web, iar dezvoltatorii ce il folosesc vor realiza
aplicatii web mai rapid decat aceeia care nu il folosesc. Ruby on Rails face dezvoltarea
softwareului simpla. Se reazizeaza rapid. Este amuzanta. Si cel mai mult? Rails este
disponibila, pe gratis, chiar acum, sub licenta de sursa deschisa MIT (open source MIT
license).
Seful: Voi face asta, CB. Si am de gand sa dau un telefon la CTC (Ops)chiar acum. Urmatorul
lucru de care am nevoie de la voi este sa imi da-ti ceva informatie despre cum pot sa invat mai
multe despre Rails. Si inca o data va multumesc. Aceasta a fost in mod clar un pret de merit
pentru o pitzza!.
SFARSIT ( a povestii noastre, dar INCEPUTUL, speram, al aventurii dumneavoastra in
RAILS!)
Resurse si Bibliografie:
Pagini web:

Aptana Compania ce a cumparat recent Ruby on Rails( http://www.aptana.com/ )


Pagina oficiala a lui Ruby: http://www.ruby-lang.org/en/
Pagina oficiala veche lui Ruby on Rails: http://www.rubyonrails.com/
Cel mai bun mod de a invata Ruby: citeste cartea gratis Programming Ruby:
http://www.rubycentral.com/book/index.html
Adresa primara pentru proiectele sursa deschisa Ruby (open source Ruby projects):
RubyForge: http://rubyforge.org/
Proiectele sursa deschisa Ruby on Rails:
http://wiki.rubyonrails.com/rails/show/OpenSourceProjects
Informatii si acorduri copyright despre folosirea Ruby on Rails:
http://wiki.rubyonrails.com/rails/show/Howtos
RailsForum: http://www.railsforum.com/viewforum.php?id=20 un excellent set de
manuale de folosire dupa cartea "Rolling with Ruby on Rails." (Lucrul cu Ruby on
Rails)

Lista de poste:

Rails mailing list: http://groups.google.com/group/rubyonrails-talk?hl=en


Ruby-talk mailing list: http://www2.ruby-lang.org/en/20020104.html

Bill Walton ( http://www.onlamp.com/pub/au/2890 ) este un dezvoltator de software


/consultant de management de proiect/contractor.

Curt Hibbs ( http://www.onlamp.com/pub/au/2890 ) a fost intodeauna usor obsedat cu


tehnologiile noi si cu urmarirea tendintelor noi in tehnologie.
Lucrare tradusa in cea mai mare parte de pe site-ul ONLamp.com. (
http://www.onlamp.com/ )
Copyright 2007 O'Reilly Media, Inc.

S-ar putea să vă placă și

  • Lab 4
    Lab 4
    Document4 pagini
    Lab 4
    Iloaie Maria Georgeta
    Încă nu există evaluări
  • Lab 3
    Lab 3
    Document5 pagini
    Lab 3
    Iloaie Maria Georgeta
    Încă nu există evaluări
  • Lab 2
    Lab 2
    Document6 pagini
    Lab 2
    Iloaie Maria Georgeta
    Încă nu există evaluări
  • Albert Einstein - Cum Vad Eu Lumea
    Albert Einstein - Cum Vad Eu Lumea
    Document165 pagini
    Albert Einstein - Cum Vad Eu Lumea
    cezara2011
    90% (50)
  • Aplicatii de Retea
    Aplicatii de Retea
    Document25 pagini
    Aplicatii de Retea
    Iloaie Maria Georgeta
    Încă nu există evaluări
  • Plasma Vs LCD
    Plasma Vs LCD
    Document10 pagini
    Plasma Vs LCD
    Iloaie Maria Georgeta
    Încă nu există evaluări