Má to řadu výhod, jednak bych se do nich jinak asi nedonutil, jednak předpokládám, že přínos bude větší, než kdybych se pouštěl do umělého internetového obchodu, který by stejně nikomu nic neřekl. Zejména z případné diskuse určitě vyplynou alternativní řešení.
O jaké stránky půjde? Umístěny budou na doméně rolldance.cz, budou pojednávat o jízdě na klasických (trackových) kolečkových bruslích a lidech kolem toho. Náplní by měly být profily uživatelů, kniha hostů, blogy, články, galerie a samozřejmě administrační rozhraní. Mimochodem vlevo nahoře.

Nejprve ale Rails nainstalujeme
1. Je třeba mít funkční Ruby. Bývá součástí běžných *nixových distribucí a mělo by být alespoň ve verzi 1.8.2. Zkuste verzi Ruby otestovat:
mig> ruby --version
ruby 1.8.3 (2005-09-21) [i686-linux]
2. Rails a případné další komponenty nainstalujeme online pomocí RubyGems. Jde o speciální balíčkovací systém určený pro snadné rozšiřování instalace Ruby. I přesto, že používáte balíčkovací systém své distribuce, můžete využít gemů. Nástroj RubyGems však nemusí být součástí vaší instalace Ruby, pročež jej budete muset doinstalovat (užitím balíčkovacího systému distribuce či stažením tarballu ze stránek projektu, jeho rozbalením a spuštěním ruby setup.rb). Předpokládejme, že RubyGems máte:
mig> gem --version
0.8.11
3. Pomocí gems nainstalujeme Rails a jejich závislosti.
mig> gem install rails --include-dependencies
Poznámka: Aktualizovat stávající verzi Rails je též snadné:
mig> gem update rails
Vytvoření projektu
Samá voda
Vstupte do adresáře, v němž chcete Rails zkoušet. Pomocí příkazu „ rails rolldance
“ v něm vytvořte podadresář rolldance obsahující celou funkční strukturu webové aplikace.
mig> cd /Depot/tempik/
mig> rails rolldance
mig> cd rolldance
mig> ls
app CHANGELOG components config db doc lib log public Rakefile README script test vendor
Co dál? Než si popíšeme některé adresáře, Rails vyzkoušíme. Nemusíte kvůli tomu instalovat Apache, pro zkušební účely využijeme http server WEBrick, který je napsán v Ruby a je součástí instalace Ruby. Rails spuštění a nakonfigurování WEBricku usnadňují jednoduchým skriptem. Upozornění: Jakékoli skripty z adresáře scripts je třeba spouštět z kořenového adresáře Rails, neboť obsahují relativní cesty. WEBrick ukončíte ctrl-c.
mig> script/server
=> Rails application started on http://0.0.0.0:3000
=> ctrl-c to shutdown server; call with --help for options
[2005-11-16 08:13:54] INFO WEBrick 1.3.1
[2005-11-16 08:13:54] INFO ruby 1.8.2 (2004-12-25) [i686-linux]
[2005-11-16 08:13:54] INFO WEBrick::HTTPServer#start: pid=12314 port=3000
V prohlížeči zadejte adresu http://localhost:3000. Měla by se objevit tato stránka:

Přihořívá
Podívejme se do adresáře public.
mig> ls public
dispatch.cgi dispatch.fcgi dispatch.rb favicon.ico images index.html javascripts stylesheets 404.html 500.html
Adresář public tvoří document root naší aplikace. To znamená, že přes url nebudou dostupné žádné adresáře o úroveň výš, čímž zůstane jejich obsah chráněn. Stránka s gratulací, kterou doufám vidíte, se nachází v souboru public/index.html. Tento soubor smažte a obnovte stránku v prohlížeči.
mig> rm public/index.html

Co se stalo? WEBrick nenalezl index.html, a proto předal požadavek Rails. Teď se tedy ukázal opravdový výstup z Rails, nikoli statická html stránka.
Hoří
Grafika stránek rolldance zatím není hotova, budeme pracovat nanečisto. Zkusíme začít Hlavní stránkou a stránkou O nás, obě budou víceméně statické a není vyloučeno, že je později úplně změníme. Jedná se jen o prototyp a prototypování je silnou vlastností Rails.
Analogicky k PHP, v následující části vyrobíme index.php a o_nas.php.
Protože jsou Rails postaveny na MVC architektuře (Model – View – Controller), je nezbytné začít alespoň kontrolérem a pohledem. Model zatím vynecháme, ač je jednou z nejsilnějších vlastností Rails, jež je odlišuje od ostatních frameworků. Náš kontrolér, pracovně nazvaný Rolldance, se bude starat o Hlavní stránku a stránku O nás.
mig> script/generate controller Rolldance
exists app/controllers/
exists app/helpers/
create app/views/rolldance
exists test/functional/
create app/controllers/rolldance_controller.rb
create test/functional/rolldance_controller_test.rb
create app/helpers/rolldance_helper.rb
Je zřejmé, že se kontroléry i pohledy nacházejí v adresáři app. Předesílám, že tamtéž v budoucnu budou všechny naše kódy, snad kromě případných externích knihoven.
mig> ls app/
apis controllers helpers models views
mig> ls app/controllers/
application.rb rolldance_controller.rb
mig> ls app/views/
layouts rolldance
Začneme úpravou kontroléru. Původně skoro prázdný soubor app/controllers/rolldance_controller.rb doplníme o metody „index“ a „o_nas“ (analogie index.php a o_nas.php).
app/controllers/rolldance_controller.rb
class RolldanceController < ApplicationController
def index
end
def o_nas
end
end
Kontrolér máme. Zbývá vytvořit odpovídající pohledy, jinými slovy soubory app/views/rolldance/index.rhtml a app/views/rolldance/o_nas.rhtml.
app/views/rolldance/index.rhtml
<h1>Hlavní stránka</h1>
dnešní datum: <%= Time.now %> (přibližně
<% if Time.now.day <= 15 %>
první
<% else %>
druhá
<% end %>
polovina měsíce )<br />
<%= link_to 'O nás', :action=>'o_nas' %>
app/views/rolldance/o_nas.rhtml
<h1>O nás</h1>
Jsme parta nadšenců, kteří bla bla bla...<br />
<%= link_to 'Zpět na hlavní stránku', :action=>'index' %>
Výsledek vyzkoušejte na adrese http://localhost:3000/rolldance či na adrese http://localhost:3000/rolldance/index. Na hlavní stránce by se mělo zobrazit datum a v závorce informace o tom, kterou půlku měsíce máme.
Jak Rails poznají, co je kontrolér a co je akce? V našem případě „rolldance“ odpovídá názvu kontroléru, „index“ akci. Pokud není akce uvedena, je defaultně použita akce index. Tato základní pravidla lze samozřejmě předefinovat.
Oddělení logiky od obsahu
Nezdá se vám šablona hlavní stránky v pořádku? Mně také ne, a ani z pohledu MVC není dobrá, neboť obsahuje programovou logiku. Vrátíme se k ní však později.
Nejdříve se podíváme na ERb (Embedded Ruby) značky v šabloně. Stejně jako v PHP 5 existují i v ERb značky dvojího typu, <% %> a <%= %>. První z nich vykonává Ruby kód, ale nic nezobrazuje, druhá vloží na své místo hodnotu posledního uvnitř provedeného výrazu, používáme ji tedy jako echo.
Značek se v šablonách hojně využívá, především ve spojení s pomocnými metodami (helpers). Jednu z nich, link_to, jsem v příkladu použil. Namísto toho, abych psal přímo <a href='/rolldance/o_nas''>O nás</a>, nahradil jsem anchor tag voláním metody link_to. Proč? Později nebudu muset měnit url ve všech šablonách, jestliže přejmenuji akci či kontrolér. Navíc táž akce a tentýž kontrolér může být dostupný ze dvou různých url.
Pomocné metody (helpers) jsou zdokumentovány v rails API, knize ukolébavek pro děti i dospělé, sekci ActionView::Helpers.
Ale vraťme se k šabloně hlavní stránky a otázce, co je v ní špatně. Jak jsem psal, obsahuje programovou logiku – určení poloviny měsíce. Zkusíme kód přemístit tam, kam patří, to jest ze šablony hlavní stránky do kontroléru a jeho metody index.
app/controllers/rolldance_controller.rb
class RolldanceController < ApplicationController
def index
if Time.now.day <= 15
@pulka = 'první'
else
@pulka = 'druhá'
end
@datum = Time.now
end
def o_nas
end
end
app/views/rolldance/index.rhtml
<h1>Hlavní stránka</h1>
dnešní datum: <%= @datum %> (přibližně <%= @pulka %>)<br />
<%= link_to 'O nás', :action=>'o_nas' %>
Hned to vypadá lépe, že? Princip kontroléru-šablony není složitý, proměnné objektu, tedy data, která „uvaří“ kontrolér, jsou dostupné v šabloně. V kontroléru tyto proměnné nastavíme, v šabloně je vytiskneme.
Ptáte se, co dělají ty zavináče? V Ruby odlišují proměnné objektu od lokálních proměnných metod; v PHP by jejich zápis odpovídal $this->pulka a $this->datum.
Layout
Možná jste si všimli, že jsem šablony záměrně neobalil počátkem ani koncem html. Učinil jsem tak proto, že společné části obou stránek nemá smysl psát do každé šablony zvlášť, nýbrž je sdílet. Sdíleným částem se říká layout a nejde o nic jiného než speciální šablonu, v našem případě soubor app/views/layouts/rolldance.rhtml. Vytvořte jej a zkopírujte do něj
app/views/layouts/rolldance.rhtml
<html>
<head><title><%= @title %></title></head>
<body>
<%= @content_for_layout %>
</body>
</html>
@content_for_layout je proměnná, která obsahuje buď zpracovaný vnitřek Hlavní stránky, nebo stránky O nás. Navíc, díky tomu, že jsou veškerá data „uvařena“ již v kontroléru, může být takto získanou proměnnou i titulek stránky. Nastavíme proměnnou @title v kontroléru tak, aby titulky stránek odpovídaly akcím.
app/controllers/rolldance_controller.rb
class RolldanceController < ApplicationController
def index
@title = 'Rolldance: Hlavní stránka'
if Time.now.day <= 15
@pulka = 'první'
else
@pulka = 'druhá'
end
@datum = Time.now
end
def o_nas
@title = 'Rolldance: O nás'
end
end
Shrňme si, co jsme zatím vytvořili. Máme kontrolér, šablony a layout. Zatím nepoužíváme žádné výstupy z databáze ani lokalizaci. Stránky jsou víceméně statické.
Debug
Autoři Rails obvykle odsouvají ladění do méně důležitých částí příruček, ale podle mých zkušeností bylo ladění tím prvním, co jsem potřeboval. Bez něj se programování stává dřinou.
Ladění výpisem do šablony I
V kontroléru z principu není možné používat echo či print_r, jak jsme zvyklí z PHP, a zobrazovat data přímo do stránky. Jediné místo, kde tento způsob můžeme použít, je šablona. Helper k účelu sloužící se jmenuje debug.
app/views/rolldance/index.rhtml
<h1>Hlavní stránka</h1>
<%= debug @pulka %>
<%= debug @datum %>
dnešní datum: <%= @datum %> (přibližně <%= @pulka %>)<br />
<%= link_to 'O nás', :action=>'o_nas' %>
Ještě jednou připomínám, že proměnné @pulka a @datum byly vytvořeny v kontroléru a nalezneme je i zde v šabloně. Abychom simulovali print_r z PHP a mohli používat jeho obdobu v kontroléru, musíme přidat, nejlépe přímo do layoutu, výpis proměnné @debug, do níž v kontroléru přiřadíme to, co chceme zobrazit.
app/controllers/rolldance_controller.rb
class RolldanceController < ApplicationController
def index
@title = 'Rolldance: Hlavní stránka'
if Time.now.day <= 15
@pulka = 'první'
else
@pulka = 'druhá'
end
@debug = @pulka
@datum = Time.now
end
def o_nas
@title = 'Rolldance: O nás'
end
end
app/views/rolldance/index.rhtml
<html>
<head><title><%= @title %></title></head>
<body>
<%= debug @debug %>
<%= @content_for_layout %>
</body>
</html>
Ladění výpisem do šablony II
Helper debug vypisuje celé objekty a činí tak s pomocí YAML. Výše uvedený příklad neumožňuje vypsat více proměnných najednou. Ukážeme si způsob, jak z proměnné @debug udělat pole, a problém tím vyřešit. Nebudeme navíc plnit přímo pole @debug, ale napíšeme speciální metodu dbg, aby to „bylo hezčí“. Vložte ji do souboru app/controllers/application.rb, jenž je zděděn ostatními kontroléry, aby byla dostupná ve všech kontrolérech.
app/controllers/application.rb:
# The filters added to this controller will be run for all controllers in the application.
# Likewise will all the methods added be available for all controllers.
class ApplicationController < ActionController::Base
def dbg item
# inicializace pole, neni-li
@debug ||= []
# pridani polozky do pole
@debug << item
end
end
app/controllers/rolldance_controller.rb:
class RolldanceController < ApplicationController
def index
@title = 'Rolldance: Hlavní stránka'
if Time.now.day <= 15
@pulka = 'první'
else
@pulka = 'druhá'
end
dbg @pulka
dbg self.instance_variables
dbg Time.now.day
dbg Time.now
@datum = Time.now
end
def o_nas
@title = 'Rolldance: O nás'
end
end
Ladění breakpointerem
Rails nabízejí skvělou možnost ladění – interaktivní vzdálenou konzoli. Nebudeme se připojovat vzdáleně, proto breakpointer (konzoli) spustíme bez parametrů
mig> script/breakpointer
o connection to breakpoint service at druby://localhost:42531 (DRb::DRbConnError)
Tries to connect will be made every 2 seconds...
Teď už nezbývá než vložit na určité místo kódu metodu „breakpoint“ s volitelnou poznámkou jako parametrem.
app/controllers/rolldance_controller.rb
class RolldanceController < ApplicationController
def index
@title = 'Rolldance: Hlavní stránka'
if Time.now.day <= 15
@pulka = 'první'
else
@pulka = 'druhá'
end
breakpoint 'koukni se na @pulka'
@datum = Time.now
end
def o_nas
@title = 'Rolldance: O nás'
end
end
Jakmile se prohlížečem podíváme na stránku, v místě breakpointu se provádění programu zastaví a Rails vytvoří server, k němuž se automaticky připojí breakpointer (konzole).
Na konzoli lze pracovat, jako kdybychom byli přímo uvnitř metody, a to v místě breakpointu. Můžeme vypisovat proměnné, nastavovat je, spouštět ostatní metody a tak dále.
Executing break point "koukni se na @pulka" at ./script/../config/../app/controllers/rolldance_controller.rb:8 in `index'
irb(#<RolldanceController:0x4087b3fc>):001:0> @pulka
=> "druha"
irb(#<RolldanceController:0x407c0584>):003:0> self.instance_variables
=> ["@datum", "@url", "@template", "@__bp_file", "@session", "@performed_redirect", "@assigns", "@request", "@__bp_line", "@pulka", "@action_name", "@action_methods", "@headers", "@response", "@performed_render", "@cookies", "@params"]
irb(#<RolldanceController:0x407c0584>):004:0> @pulka = 'prvni'
=> "prvni"
Pokud hledáte nějakou proměnnou či metodu, mohou vám posloužit výpisy z těchto metod:
self
self.methods
self.instance_variables
Breakpointer ukončíte ctrl-d a program bude pokračovat v běhu.
Logování
Poslední způsob, o němž se chci dnes zmínit, je logování. Výstup loggeru najdete v souboru log/development.log. (Jak se liší development, production a test, bude objasněno v příštím dílu, nyní si řekněme jen to, že Rails mohou fungovat v několika stavech, které například ovlivňují právě logování. Development patří mezi „ukecané“ stavy, takže v logu naleznete i provedené SQL dotazy s jejich dobou trvání. Přepnout stav je možné změnou proměnné prostředí RAILS_ENV.)
Logger se používá jednoduše; kromě metod info a fatal existují ještě metody warn a error.
app/controllers/rolldance_controller.rb
class RolldanceController < ApplicationController
def index
logger.info 'INFO: Jsme v metode index'
@title = 'Rolldance: Hlavní stránka'
if Time.now.day <= 15
@pulka = 'první'
else
@pulka = 'druhá'
end
logger.fatal 'FATAL ERROR: chyba Ruby' if @pulka != 'prvni' && @pulka != 'druha'
@datum = Time.now
end
def o_nas
@title = 'Rolldance: O nás'
end
end
Závěr
V příštím dílu si povíme o práci s hezkými url (pretty-url) a konečně použijeme model, který jsme zatím ignorovali.