Ruby on Rails to framework, który cieszy się niesłabnącym zainteresowaniem w kręgach projektantów aplikacji internetowych. Jego główną zaletą ma być szybkość tworzenia i wdrażania nowych rozwiązań. Postanowiliśmy sprawdzić, czy to prawda.
Do Ruby on Rails podeszliśmy zrazu bardzo
sceptycznie. Ot, nowe rozwiązanie, które
narzuca programiście swój styl programowania
i ma niewiele praktycznych wdrożeń. Na
niekorzyść Rails przemawia przerażający brak
literatury specjalistycznej. Choć nie jesteśmy zwolennikami
polskich przekładów \”cegieł\”, to jednak
wiemy z doświadczenia, że tylko one pozwalają na
poznanie nowej technologii tak, jak lubimy – od
podszewki. Zraził nas brak platform hostingowych
wspierających Rails. Po co mamy tworzyć
programy w słabo dostępnej technologii, której nie
można uruchomić nigdzie poza własnym serwerem
lokalnym?
Próba zaprezentowania Rails w bezstronny
sposób szybko więc spaliła na panewce. Wszystko
dlatego, że chcieliśmy bez zwłoki odkryć
przed Czytelnikiem wszystkie potencjalne wady
rozwiązania, które z punktu widzenia zawodowego
programisty zajmującego się wdrażaniem
rozbudowanych aplikacji internetowych jest
bliskie ideału. Tak, Ruby on Rails wywarło na nas
nieodparte wrażenie, że zawiera wszystko, czego
dotychczas brakowało w innych frameworkach,
a tu magicznie zostało rozwiązane w bardzo
przystępny sposób.
Ruby on Rails to framework, czyli ramowe
środowisko pracy, projektowania. Zadaniem
frameworków jest dostarczanie programiście
szkieletu programu, które ułatwi mu realizację
powtarzających się zadań, takich jak uwierzytelnianie
czy walidacja danych przychodzących. Każdy
framework bazuje na określonym języku programowania,
w którym go napisano. W przypadku
Rails jest to język obiektowy Ruby, początkowo
mało znany, który zyskał na popularności wraz
z rozwojem Rails.
Środowisko Rails wychodzi o krok do przodu
ponad inne rozwiązania, starając się do maksimum
ułatwić pracę programiście. Efektem jest
stworzenie ideologii, która zmusza programistę do
wykonywania ściśle określonych czynności w celu
osiągnięcia rezultatu. Za punkt honoru wzięto tu
sobie dwie reguły:
- Don’t Repeat Yourself (DRY) – nie powtarzaj się,
- Convention Over Configuration – konwencja
ponad konfiguracją.
Zasada DRY jest dobrze znana wśród programistów
i nie jest niczym nowym. Unikanie tworzenia
identycznych fragmentów kodu jest niejako wpisane
w ten zawód. Zaletą tworzenia zorientowanego
obiektowo kodu opartego o klasy, metody czy biblioteki
jest możliwość efektywnego dokonywania
zmian. W celu poprawy wybranej funkcjonalności
wystarczy zmodyfikować daną klasę czy metodę
jeden raz, unikając szukania rozwiązań bazujących
na tym samym fragmencie kodu.
Rails stara się tę zasadę jeszcze bardziej rozszerzyć,
próbując objąć nią każdy fragment pisanego
kodu. To dlatego niekonieczne jest choćby pisanie
zapytań SQL (tak, w Rails nie piszę się absolutnie
żadnych zapytań SQL), czy tworzenie kontrolerów
do obsługi żądań. Idąc dalej, Rails zakłada, że
pracujemy na bazie danych i jest to baza MySQL.
Co więcej, Rails zakłada nawet, że indeksem każdej
używanej tabeli jest pole o nazwie id i jest ono
polem typu auto_increment.
Z początku to, że Rails narzuca takie wymogi
naszej pracy, wydaje się nieco kontrowersyjne.
Z czasem zdajemy sobie jednak sprawę, że reguły
narzucane przez Rails są bardzo przydatne. Nie
musimy bowiem zastanawiać się nad lokalizacją
klas czy jakichkolwiek innych plików. W projekcie
panuje pełny ład. Co więcej, w Rails nawet nazwy
tworzonych klas powinny odpowiadać nazewnictwu
używanych tabel.
Tak rodzi się reguła \”konwencji
ponad konfiguracją\”, która sprawia, że Rails zawsze czyni założenia, starając się zautomatyzować
nawet niektóre żmudne czynności. Oczywiście,
założenie Rails może być błędne. Wówczas
konieczna jest zmiana domyślnej konfiguracji Rails.
Robimy to jednak tylko w szczególnym przypadku,
a w dodatku dość rzadko. We wszystkich
pozostałych sytuacjach Rails uznaje przyjęte reguły
za obowiązujące i programista nie musi już sobie
zaprzątać głowy sprawami niezwiązanymi bezpośrednio
z programowaniem.
Organizacja dowolnej aplikacji napisanej
w oparciu o Rails jest zrozumiała dla każdego, kto
zna ten framework. W Rails konwencje nazewnicze
dotyczą nie tylko pisanego kodu czy tworzonych
tabel. Wszystkie elementy tworzonego przez nas
projektu są podporządkowane regułom. W ten
sposób funkcjonuje zarówno struktura katalogów,
która narzuca nam organizację naszego projektu,
jak i nazewnictwo poszczególnych modeli, widoków
i kontrolerów. Dzięki takiemu zabiegowi, Rails
pozwala na łatwą budowę projektu przez grupę
programistów. Sprawdzi się także i wtedy, gdy
porzucony projekt jest reaktywowany przez innego
programistę. Czas potrzebny do oswojenia się
z projektem jest bardzo krótki, gdyż z góry wiadomo,
w jaki sposób projekt został zorganizowany.
MVC
Większość współcześnie tworzonego oprogramowania
– czy to aplikacji okienkowych, czy internetowych
– jest oparta o paradygmat model-widok-
kontroler. Celem wzorca projektowego MVC
(ang. Model View Controler) jest oddzielenie logiki
biznesowej od logiki prezentacji. Rails implementuje
paradygmat MVC w postaci dostosowanej do
standardów aplikacji internetowych (znany także
pod nazwą Model2 czy \”model trójwarstwowy\”).
Za sterowanie całą aplikacją odpowiada kontroler,
którego zadaniem jest pobranie i walidacja
informacji pochodzących od użytkownika oraz
wysłanie prośby o pobranie danych realizowane
przez model. Model odpowiada za wszystkie
procesy związane z zachowaniem się aplikacji, czyli
pobieraniem danych i ich manipulacją. Wszystko to
wykonywane jest po to, by ostatecznie przekazać
dane widokowi. Widok podejmuje decyzję
o danych, które należy przekazać i przygotowuje
informację zwrotną dla użytkownika, najczęściej
w postaci strony WWW.
Komponenty Ruby on Rails
Aby uruchomić Ruby on Rails na dowolnym
serwerze, czy to developerskim (zlokalizowanym
u nas w domu), czy produkcyjnym (zlokalizowanym
zwykle w firmie hostingowej), konieczna jest
instalacja kilku komponentów. Rails to bowiem
jedynie biblioteka rozszerzająca język programowania
Ruby.
Do uruchomienia programu opartego o RoR
potrzebny będzie:
- Serwer http obsługujący żądania.
- Baza danych, standardowo RoR wspiera MySQL, choć nie ma przeciwwskazań, by używać PostgreSQL, czy SQLite.
- Dystrybucja Ruby skonfigurowana do pracy z serwerem http.
- Zainstalowany komponent RoR do Ruby.
Dostępne serwery http:
- WEBrick, napisany w Ruby, http://webrick.org.
- Apache, najpopularniejszy w sieci serwer, bardzo wydajny, lecz słabo wspierający RoR, trudny do skonfigurowania, http://apache.org.
- lighttpd, bardzo szybki z nieco lepszym wsparciem RoR niż Apache, http://www.lighttpd.net.
- Mongrel, szybki, dostosowany do potrzeb RoR, polecany do obsługi Ruby, http://mongrel.rubyforge.org/.
Rusztowania
Ruby on Rails jest narzędziem przeznaczonym
dla praktyków, którym zależy na szybkim osiąganiu
rezultatów swojej pracy. Właśnie dlatego powstało
narzędzie o nazwie rusztowanie (ang. scaffold).
Zamysłem stojącym za takim rozwiązaniem jest
chęć zapewnienia programiście szybkiego startu
przy tworzeniu aplikacji.
Rails na podstawie wskazanej przez programistę
tabeli w bazie danych automatycznie tworzy
wszelkie narzędzia potrzebne do zarządzania
zawartością tabeli. Jak zdążyliśmy zauważyć, otrzymujemy
całkiem spory pakiet możliwości:
- Przeglądanie artykułów dodanych (list)
- Dodawanie nowych artykułów (new)
- Edycję artykułów (edit)
- Oglądanie poszczególnych artykułów (show)
- Usuwanie artykułów (destroy)
Ruby wszystkie te podstrony tworzy automatycznie
i dynamicznie. Słowo dynamicznie oznacza
w tym przypadku, że w momencie zmiany koncepcji
tabeli w bazie danych nastąpi automatyczne
przystosowanie rusztowania do nowego modelu
danych. Załóżmy, że chcesz dodać do swoich
artykułów jeszcze dodatkowy wstęp. Wystarczy, że
zmienisz strukturę tabeli, a wszystkie formularze
występujące w rusztowaniu zostaną przebudowane.
Dynamika rusztowania ma oczywiście pewne
wady. Rusztowanie niestety nie jest napisane
w języku polskim, niekoniecznie odpowiada każdemu
pod względem graficznym, natomiast adresy
używane przez rusztowanie nie są dla polskiego
użytkownika zbyt atrakcyjne.
Tym samym dochodzimy do wniosku, że
dobrym rozwiązaniem byłaby możliwość wygenerowania
wszystkich plików tworzących rusztowanie
w taki sposób, aby możliwa była ich łatwa
modyfikacja. Do tego celu posłuży nam jeszcze raz
nasz generator. Wprowadzając polecenie:
generate scaffold Article
sprawisz, że nasze rusztowanie staje się statyczne.
Łatwo zauważyć, że program utworzył dość sporo
plików. Zauważalna jest obecność wielu plików
widoku, zakończonych końcówką .rhtml. Poddaj je
edycji, aby przetłumaczyć zawarte w nich teksty na
rodzimy język.
Przykładowo tytuły nagłówków miały nazwę
zgodną z nazwami pól w tabeli. Jeżeli chcesz przetłumaczyć
tytuły na bardziej intuicyjne, zmodyfikuj
kod HTML:
Tytuł
Treść
Data dodania
Akcja
W tym przypadku trzeba niestety zrezygnować
z dynamicznego charakteru generowanych
nagłówków tabeli na rzecz właściwych nazw.
Oczywiście możliwości narzędzia rusztowanie są
w pewnym stopniu ograniczone. Tu otwiera się
pole do popisu przed programistami, którzy utworzywszy
statyczną wersję rusztowania, mogą do
woli modyfikować zawartą w nim funkcjonalność.
W praktyce okazuje się, że narzędzia ułatwiające
prototypowanie pozwalają zaoszczędzić wiele
pracy, która musi być siłą rzeczy ręcznie wykonana
przez programistę. Rozszerzenie możliwości naszej
bazy artykułów może polegać na dodaniu logowania.
Tylko zalogowany użytkownik widziałby
przyciski edytuj, usuń czy dodaj.
Dodatkowo,
RoR oferuje bardzo łatwą metodę na podzielenie
wyników na strony. Przyda się to niemal zawsze,
gdyż liczba artykułów na stronie musi być w jakiś
sposób ograniczona.
Active Record
Przeglądając kod programu, zauważyłeś
z pewnością, że brak w nim jakichkolwiek zapytań
SQL czy problemów związanych z poprawnym
przechwyceniem wyników. Wszystko dlatego, że
RoR oferuje mapowanie relacyjno/obiektowe (ang.
ORM). Pod tą skomplikowaną nazwą kryje się
technologia, która została wdrożona w RoR pod
nazwą Active Record.
Dzięki wykorzystaniu możliwości metaprogramowania
(tworzenia przez program komputerowy
programów), oferowanego przez Ruby i zalet konwencji
nazewniczych, możliwe stało się stworzenie
interesującego systemu mapowania bazy danych
w sposób obiektowy. Active Record to wbudowane
na stałe narzędzie przejmujące kontrolę
nad wszystkimi zapytaniami wysyłanymi do bazy
danych. Zapytania od strony aplikacji internetowej
dzielą się na cztery typy: utwórz, odczytaj, aktualizuj,
usuń. Tak powstał skrót CRUD (ang. Create
Read Update Delete).
Wzorzec projektowy MVC narzuca na RoR
konieczność obsługi modelu danych. To pole
zostało całkowicie oddane na rzecz ActiveRecord.
Utworzenie nowego modelu danych powoduje, że
RoR na podstawie nazwy klasy odnajduje tabelę
w bazie danych, którą stara się przedstawić w postaci
obiektu. Każdej instancji obiektu powstałego
w skutek analizy struktury tabeli odpowiada rekord
w bazie danych. To co prawda tworzy znaczący narzut
niepotrzebnych danych przechodzących z bazy
do środowiska, lecz w bardzo znacznym stopniu
ułatwia programowanie.
ActiveRecord pozwala na implementację
typowych zależności występujących w bazie
danych, czyli np. dowiązań jeden do wielu, wielu
do wielu, jeden do jednego. Wszystkie te czynności
odbywają się automatycznie z uwagi na przyjęte
nazewnictwo. Przykładowo, jeżeli nasz system
artykułów rozszerzymy o kategorie, do których
zaliczają się artykuły, konieczne będzie stworzenie
odpowiedniego rozwiązania. Do tabeli articles
wystarczy dodać nazwę category_id i utworzyć
tabelę z nazwami kategorii o odpowiadającej
nazwie – categories. Po podaniu przez programistę
tej zależności, ActiveRecord automatycznie utworzy
powiązanie.
Wydajność
Rails nie należy do rozwiązań najszybszych.
Choć brak jednoznacznych testów mogących
wykluczyć Rails jako rozwiązanie mało wydajne, to
łatwo wyobrazić sobie, czym tak naprawdę Rails
się zajmuje, gdy wprowadzamy jedną linię kodu.
Funkcjonalność i magia Active Record jest z pewnością
godna naśladowania. Niestety, ponieważ
każdy rekord pobrany z bazy danych jest instancją
klasy tworzonej dynamicznie na podstawie tabeli
z bazy, cała ta operacja wymaga poświęcenia dużej
ilości czasu pracy procesora serwera. Rails trudno
więc nazwać wydajnym rozwiązaniem właśnie
dlatego, że zawsze przechowuje wiele danych
nadmiarowych.
Dodatkowa trudność administracji frameworkiem
w profesjonalnym hostingu sprawia, że na
instalację Rails na swoich serwerach zdecydowała
się garstka usługodawców na świecie. Sytuacji
nie poprawia fakt, że Rails znacząco obciąża
serwerownie, co z kolei pociąga za sobą wyższe
koszty sprzętu.
Ruby on Rails nadaje się znakomicie do
tworzenia małych i średnich witryn, lecz całkowicie
odpada w przypadku rozwiązań rozbudowanych.
Wydaje się, że głównym konkurentem jest tu język
PHP, który wymaga jednak włożenia znacznie większego
wysiłku w celu osiągnięcia takiego samego
rezultatu. Choć oba rozwiązania nie są demonami
szybkości, to z uwagi na wymienione wyżej
przyczyny, Ruby on Rails jest znacznie wolniejszym
rozwiązaniem.
Z uwagi na cechy wyróżniające Rails (szybkość
implementacji = niski koszt programu), narzędzia
takie jak Scaffolding i Active Record czy na łatwą
implementację AJAX-a, chętnie stworzylibyśmy
w Rails panel administracyjny do zarządzania
stroną. Jednak jeżeli chodzi o samą witrynę,
zalecalibyśmy wykorzystanie PHP lub Pythona.
Jeżeli projekt wymagałby bardzo dużej wydajności,
zdecydowalibyśmy się na C++ lub Javę
(i framework Struts).
Podsumowanie
W artykule udało nam się zaledwie nakreślić
możliwości platformy Rails. Główną przeszkodą,
z jaką spotka się uczący się tej technologii programista,
jest zazwyczaj słaba znajomość języka programowania
Ruby. Choć zasady programowania są
zbliżone do C++ czy Javy, to Ruby (wraz z Rails)
wymaga ścisłego stosowania się do konwencji
nazewniczych i używania wielu dość nietypowych
właściwości samego języka.
Poznaj Aptana IDE
Każdy z programistów ma zestaw ulubionych
programów, z którymi pracuje. Ruby on Rails
co prawda nie ma oficjalnego zintegrowanego środowiska
programistycznego, lecz istnieje program,
który aspiruje do takiego miana. Początkowo
znany pod nazwą RadRails, obecnie przekształcił
się w IDE o nazwie Aptana.
Aptana jest bezpłatnym, zintegrowanym środowiskiem
programistycznym o ogólnym przeznaczeniu,
dzięki czemu pozwala na edycję kodu
źródłowego napisanego w różnych językach programowania
i metajęzykach (CSS, XML, XHTML).
To, co sprawia, że staje się bardzo funkcjonalny
dla programistów Ruby on Rails, to dodatkowe
rozszerzenie. Zaraz po instalacji Aptana mamy
możliwość doinstalowania przez sieć Aptana Rad-Rails.
Obok standardowych możliwości programu
typu IDE, takich jak praca na zdalnym serwerze
FTP/SFTP, Aptana podświetla składnię lub pozwala
na przeglądanie testów aplikacji w osobnym
oknie. Oczywiście nie zabrakło także debugera
kodu źródłowego, czy możliwości szybkiego wykonywania
skryptu generatora.
http://www.aptana.com
Przeczytałeś i uważasz artykuł za ciekawy? Polecamy \”Internet Makera\”
Kontroler HelloWorld
Jeżeli teraz uruchomisz przeglądarkę internetową,
wpisując adres:
http://localhost:3001/test/hello_world
otrzymasz komunikat błędu. Faktycznie, nie istnieje
akcja określająca zachowanie się programu w takiej
sytuacji.
Edytujemy więc plik app/controllers/hello_world_controller.rb, tak aby jego zawartość
wyglądała następująco:
class HelloWorldController < Application-Controller
def index
render :text => \"Witaj Świecie!\"
end
end
Tworząc dodatkową metodę index, dodajemy
obsługę adresu /hello_world/. Ponowne jego
wpisanie do przeglądarki skutkuje wyświetleniem
komunikatu.
Jeżeli zechciałbyś utworzyć dodatkową akcję,
wystarczy, że dopiszesz kolejną metodę:
def narazie
render :text => \"Do zobaczenia!\"
end
Wówczas wprowadzenie do przeglądarki
adresu http://localhost:3000/hello_world/ na razie
skutkować będzie wyświetleniem komunikatu \”Do
zobaczenia!\”.
Tworzenie widoku
Rails bazuje nieustannie na konwencjach. Wywołanie
metody index skutkuje tym, że RoR szuka
w katalogu app/views/hello_world pliku o nazwie
index.rhtml. Oczywiście nie ma sensu takiego pliku
tworzyć ręcznie. Posłużmy się znanym już nam
generatorem:
ruby script/generate controller Hello-World index
W trakcie wykonywania skryptu zostaniesz
zapytany o nadpisanie istniejącej klasy kontrolera.
Wprowadź \”n\”, gdyż nie chcesz pozbyć się efektów
dotychczasowej pracy.
Z klasy kontrolera usuń linię:
render :text => \"Witaj Świecie!\"
zastępując ją:
@hello_world = \"Witaj Świecie\"
Gdy w tym momencie przejdziesz na naszą
stronę, otrzymasz komunikat:
HelloWorld#index
Find me in app/views/hello_world/index.rhtml
Informuje on o fakcie odwołania się do widoku,
szablonu strony. Poddaj edycji plik app/views/hello_
world/index.rhtml, aby zmodyfikować go do
postaci:
<%= @hello_world %>
Współpraca z bazami danych
Utwórz teraz tabelę w bazie danych. Tabela ta
będzie przechowywać aktualne artykuły. Skorzystaj
z narzędzia MySQL Query Browser, aby zalogować
się do bazy danych test_development. Ponieważ ta
baza jeszcze nie istnieje, konieczna jest akceptacja
monitu z pytaniem o jej stworzenie. Dane do
połączenia z bazą znajdziesz w pliku config/database.yml.
Po nawiązaniu połączenia ustal strukturę bazy
danych. Będzie ona wyglądała następująco:
- id – identyfikator wiersza,
- title – tytuł artykułu,
- text – treść artykułu,
- datetime – czas pierwotnego opublikowania
artykułu.
Konwencje nazewnicze w RoR dotyczą także
tabel w bazach danych. Kontroler odpowiedzialny
za obsługę artykułu powinien przyjąć nazwę
Article, natomiast tabela w bazie zawierająca wiele
artykułów powinna występować w liczbie mnogiej
– articles. Niestety, owa reguła nie zadziała dla
nazw polskich. Bardzo możliwe jednak, że kiedyś
uda się stworzyć polską wersję tego rozwiązania.
Teraz utwórz odpowiedni model danych, czyli
trwałe połączenie programu z określoną tabelą
w bazie. W naszym przykładzie konieczne jest,
by RoR współpracowało z naszą tabelą articles.
Wykonaj polecenie mające na celu wygenerowanie
modelu:
ruby script/generate model Article
Do działania model wymaga sterownika,
kontrolera. Utwórz teraz kontroler o tej samej nazwie.
Kontroler Article należy tworzyć, korzystając
z bardzo zbliżonego polecenia:
ruby script/generate controller Article
Nasz program jest już prawie gotowy! Przystąp
teraz do edycji klasy kontrolera, wprowadzając
następujący kod:
class ArticleController < ApplicationController
scaffold :article
end
Możesz już teraz uruchomić przeglądarkę pod
adresem: http://localhost:3001/article/list.
Klikając na \"New article\", ujrzysz formularz pozwalający
na dodanie nowego artykułu. Wypełnij
go. Po utworzeniu artykułu ukaże się spis aktualnych
tematów. Co więcej, nowo dodany artykuł
można zobaczyć (Show) czy edytować (Edit).
Celowo nie objaśnialiśmy wcześniej mechanizmu,
wedle którego działa cały ten program. Na
razie powinieneś zauważyć, że w zaledwie kilku
linijkach kodu utworzyliśmy swoiste rusztowanie
naszego programu. Oczywiście, wiele rzeczy nam
nie pasuje - wystrój graficzny czy chociażby angielskie
nazwy odnośników i tytułów. To wszystko jest
jednak łatwe do zmiany.
Trzy środowiska pracy
Ruby on Rails to środowisko pracy oferujące
profesjonalne właściwości, takie jak rozdzielenie
baz danych na rozwojową, testową i produkcyjną.
Trzy bazy pozwalają na wprowadzanie
zmian w sposób poprawny, tak by możliwie jak
najefektywniej wychwycić wszystkie możliwe błędy
jeszcze w procesie projektowania.
Za konfigurację bazy danych odpowiada katalog
db/, w którym umieszczono plik database.yml.
Jego edycja pozwoli nam przekonać się o trzech
dostępnych sekcjach, dla każdej z których ustalane
są osobne dane konfiguracyjne:
Development - baza używana w etapie projektowania
aplikacji, pozwalająca na nanoszenie
zmian w programie bez konieczności martwienia
się o naruszenie struktury już działającego
programu. Wielu programistów korzysta
z dwóch baz danych, gdzie baza developerska
znajduje się na maszynie lokalnej, natomiast
baza produkcyjna na hoście zdalnym. Baza
developerska nie może być używana jako
baza produkcyjna. Rails wykorzystuje pewne
mechanizmy buforowania i nie przeładowuje
wszystkich klas za każdym razem, gdy nadejdzie
żądanie z serwera.
Test - RoR wymusza od programisty tworzenie
testów dla swoich aplikacji. Ponieważ testy jak
najbardziej obejmują modyfikacje bazy danych,
konieczne jest bezpieczne środowisko, w którym
możliwe będzie swobodne dodawanie i usuwanie
danych. Ponieważ testowa baza danych jest
czyszczona przed przeprowadzeniem testu, nie
warto łączyć konfiguracji testowej z produkcyjną
czy developerską.
Production - docelową bazą jest baza produkcyjna,
której spójność i bezbłędność jest
czynnikiem najważniejszym. Bazy produkcyjne
zawierają najczęściej istotne informacje (aktualne
i archiwalne dane), których zaburzenie może
być zagrożeniem dla całego projektu.
Tworzymy projekt
Skoro znasz już strukturę przykładowego
projektu, pewnie zastanawiasz się teraz, jak
stworzyć tak rozbudowaną sieć samodzielnie.
Rails to nie tylko dodatkowe klasy do obsługi
samego programowania, lecz także zestaw
narzędziowy do wykonywania wszystkich
powtarzalnych zadań. Jednym z takich zadań
jest niewątpliwie tworzenie nowego projektu.
Przejdź do konsoli, klikając na przycisk \"I\",
a następnie wybierz \"Rails Applications\" i \"Open
Ruby Console Window\".
Aby utworzyć nowy projekt, wprowadź polecenie:
rails test
Rails jest skryptem Ruby, podczas gdy test jest
nazwą projektu, który chcemy utworzyć. W systemach
linuksowych wystarczy przejść do typowej konsoli i wprowadzić z dowolnej lokacji polecenie
\"rails nazwa_projektu\", przy czym należy zwrócić
uwagę na lokalizację, w której zostaną utworzone
wszystkie pliki.
Efektem działania programu jest utworzenie
kompletnego projektu, lecz wciąż na tyle pustego, by nie zawierał żadnych istotnych klas.
Uruchomienie naszego projektu w tym momencie zaowocuje
pojawieniem się komunikatu o poprawnym utworzeniu
nowego projektu.
Obsługa żądań i konwencje nazewnicze
Nasz szkielet projektu należy teraz wzbogacić
o elementy takie jak nowe kontrolery, widoki czy
modele. Każda klasa w RoR ma swój oddzielny
plik. W RoR konwencje nazewnicze odgrywają
ogromne znaczenie. Dlatego, gdy zechcesz utworzyć
kontroler o nazwie HelloWorld, nazwa klasy
kontrolera będzie brzmiała HelloWorldController,
a nazwa pliku kryjącego klasę będzie postaci
hello_world_controller.rb. Gdy zajrzysz do katalogu
views (widoki), okaże się, że właśnie został tam
utworzony katalog hello_world. W RoR wszystkie
nazwy muszą być ze sobą zgodne.
W Ruby nazwy klas są pisane wielką literą.
Aby nie tworzyć plików składających się z małych
i dużych znaków, przyjęto konwencję, według
której nazwa klasy zamieniana jest na małe litery.
W miejscach, gdzie występuje powtórzenie dużej
litery, wprowadzono podkreślenie. Nazwy klas nie
mogą oczywiście zawierać polskich liter.
Gdy użytkownik wprowadza w przeglądarce
adres w postaci http://www.mojastrona.pl/moj_
kontroler/moja_akcja/2321, RoR dokonuje analizy
adresu URL. Framework analizuje plik ze ścieżkami
(config/routes.rb) i odkrywa następujący zapis:
map.connect \':controller/:action/:id\'
Postępując wg powyższego schematu, RoR
analizuje adres URL. Pierwszy element określony
w adresie URL nawą \"mój_kontroler\" będzie zawsze
odwoływał się do klasy o nazwie MojKontroler.
W tej klasie RoR odnajdzie metodę MojaAkcja.
Ostatni element adresu, 2321, oznacza najpewniej
identyfikator w pewnej tabeli w bazie danych. RoR
postępuje za każdym razem tak, jak określono to
w pliku routes.rb. Domyślnym zachowaniem jest to
przedstawione powyżej.
Ponieważ adresy URL nie mogą zawierać
polskich znaków diaktrycznych, programista RoR
powinien używać języka angielskiego podczas programowania
bądź nie stosować podczas pisania
polskich znaków.
Script/generate
Utworzymy teraz nowy kontroler. Wykorzystamy
do tego celu script/generate, którego zadaniem
jest przygotowywanie struktury i zawartości
nowych elementów projektu.
Aby utworzyć nowy kontroler, wprowadź:
ruby script/generate controller HelloWorld
Efektem działania programu jest utworzenie
zestawu plików wg schematu omówionego w poprzednim
punkcie.
Instant Rails
Uruchomienie całej platformy testowej krok po
kroku wymagałoby dużo pracy, gdyż należy chociażby
pobrać dystrybucje wszystkich komponentów
potrzebnych do uruchomienia RoR. Dlatego
postanowiliśmy skorzystać z gotowca. Instant Rails
to pakiet zawierający wszystko, co potrzebne do
uruchomienia RoR praktycznie od zaraz. Wszystko
w jednym archiwum zip, o objętości 60MB. Pakiet przeznaczony jest dla systemu Windows, można
go pobrać spod adresu: http://rubyforge.org/frs/?group_id=904.
Po pobraniu pliku warto go rozpakować do
głównego katalogu jednego z dysków. My umieściliśmy
pliki w katalogu c:\\InstantRails\\. Następnie
uruchom plik Instant Rails.exe. Jeżeli w tym momencie
pojawiają się komunikaty błędu, najpewniej
oznacza to, że masz już uruchomiony proces
Apache czy MySQL.
Dlatego nic się nie stanie, jeżeli
zignorujesz te komunikaty. Nic nie stoi również na
przeszkodzie, abyś mógł wykorzystać istniejącą
instancję bazy MySQL do współpracy z Ruby.
Wraz z Instant Rails do pakietu trafił przykładowy
program, Cookbook (książka kucharska). Jest to
przykładowa aplikacja napisana w ramach jednego
z angielskojęzycznych artykułów dostępnych
w sieci. Zaraz wykorzystamy ją do sprawdzenia,
czy wszystko działa prawidłowo.
Projekty pisane w ramach RoR umieszczane są
w określonym katalogu. W Instant Rails wszystkie
projekty znajdują się w katalogu rails_apps. Tutaj
każdemu projektowi odpowiada jeden katalog
i jest to reguła. Wewnątrz znajduje się kolejny
zbiór katalogów, które tworzą pełną, regularną
strukturę aplikacji napisanej w oparciu o RoR.
Wraz z uruchomieniem Instant Rails odpalona
zostaje usługa Apache i MySQL. Nam Apache nie
będzie potrzebny, gdyż do pracy z Rails wykorzystamy
serwer Mongrel. Jedynym zastosowaniem
Apache\'a może być chęć skorzystania z administratora
bazy danych. Można do tego celu wykorzystać
zainstalowany na serwerze Apache phpMyAdmin
lub pobrać z witryny mysql.com bezpłatny program
okienkowy do zarządzania bazą MySQL Query
Browser (http://dev.mysql.com/downloads/gui-tools/5.0.html). Choć sam RoR nie zmusza do
korzystania z zewnętrznych programów do obsługi
bazy danych, warto mieć wgląd na to, co dzieje się
za naszymi plecami.
Uruchomienie przykładowej aplikacji wymaga
utworzenia osobnej instancji serwera http Mongrel.
W tym celu kliknij na ikonkę \"I\" i wybierasz
z dostępnych opcji \"Rails Applications\" i \"Manage
Rails Applications\".
Zaznacz aplikację \"Cookbook\" i wybierz opcję
\"Start with Mongrel\". W tym momencie ujrzysz
uruchamiający się proces serwera w postaci
okna konsoli. Wprowadź do przeglądarki adres
http://localhost:3001, aby ujrzeć działający projekt
RoR.
Ponieważ w momencie instalacji InstantRails
baza danych zawierała już wszystkie konieczne
dane (strukturę tabel i ich zawartość), niepotrzebne
jest tworzenie nowej bazy. Jeżeli korzystasz z innej
instancji MySQL, możesz pokusić się o wykonanie
na bazie danych pliku cookbook.sql z katalogu db/
projektu. Dodatkowo konieczne będzie przestawienie
danych konfiguracyjnych umieszczonych
w katalogu config, w pliku database.yml.
Struktura katalogów
Każdy projekt Rails zbudowany jest w oparciu
o stałą strukturę katalogów, której rozszerzanie czy
zmienianie jest mocno niewskazane. Zobaczmy, do
czego służą poszczególne katalogi.
apps
Katalog apps jest najistotniejszą częścią każdego
projektu. Jego podkatalogi mają za zadanie gromadzić klasy modeli
(ang. models), kontrolerów
(ang. controllers)
oraz skryplety (szablony)
stron - widoki (ang. views). Dodatkowo
przygotowano katalog
helpers na klasy pomocnicze
dla modelu,
widoku i kontrolera.
components
Przeznaczeniem tego
katalogu są krótkie,
nierozbudowane skrypty
narzędziowe, niekoniecznie
wykonane wg
wzorca MVC.
config
Katalog konfiguracyjny,
pozwalający na
ustalenie parametrów
pracy bazy danych
(database.yml) i zmianę
domyślnych ustawień
frameworka. Tutaj także
możesz dokonać zmian w sposobie, w jaki chcesz,
aby żądania URL były zamieniane na prezentacje
konkretnych podstron (routes.rb).
db
Tworzenie każdego projektu należy rozpocząć
od przygotowania prototypowej struktury bazy
danych. Katalog db przewidziano na zapis informacji
o tym, jak ma wyglądać struktura modelu
danych. Można tu umieścić plik SQL z zapytaniami
tworzącymi pełną strukturę bazy danych.
doc
Język Ruby jest nastawiony na dynamiczne
tworzenie dokumentacji i pisanie testów jednostkowych.
Zadaniem katalogu doc jest przechowywanie
aktualnie wygenerowanej dokumentacji technicznej
do projektu. Aby taka dokumentacja mogła zostać
poprawnie wygenerowana, konieczne jest zachowywanie
podczas tworzenia kodów odpowiednich reguł
tworzenia komentarzy. Więcej o tych praktykach można
przeczytać w rozdziale 16 książki \"Programowanie
w języku Ruby\" (wydawnictwo Helion, 2007).
lib
Katalog przeznaczony na biblioteki.
log
Środowisko Rails pozwala na ciągłe śledzenie
błędów w aplikacjach, które tworzymy. Ponieważ
dobra sygnalizacja błędów jest podstawą szybkiego
sukcesu, istnieją cztery pliki z logami. Mamy
zatem trzy pliki do obsługi trzech środowisk pracy
bazy danych oraz jeden plik z błędami zgłaszanymi
przez serwer.
public
Katalog public pełni funkcję kontenera na
wszystkie treści, które w projekcie są statyczne.
Poza statycznymi stronami HTML wyświetlanymi w wyniku napotkania błędu serwera (błąd 404),
do tego katalogu trafiają wszystkie skrypty JavaScript
(javascripts/) czy arkusze stylów CSS (stylesheets/)
używane w projekcie. Ponieważ RoR oferuje mocne
wsparcie dla techniki AJAX, to wraz z pustym projektem
otrzymujesz także zestaw bibliotek (w tym
bibliotekę Prototype oraz scripts.aculo.us).
script
Katalog gromadzi skrypty środowiska RoR
wykorzystywane do rozmaitych celów - np. generowania
kodu czy uruchamiania nowej instancji
serwera.
test
Katalog przewidziano na wszelkie testy związane
z testowaniem poprawności aplikacji w środowisku
testowym.
tmp
Tutaj umieszczane są wszelkie pliki tymczasowe,
generowane głównie przez Rails, choć
i programista może z niego korzystać.
vendor
Katalog przeznaczono na biblioteki zewnętrzne,
przygotowane przez obce firmy.