Przedm ow a.......................................................................................... 5 Informacje o k s ią ż c e ............................................................................8 P o czątk i................................................................................................ 8 RubyG em s............................................................................................ 8 Polecenia oraz konfiguracja R a ils .................................................... 12 Środow iska..........................................................................................31 R a k e .................................................................................................... 40 Testowanie R a ils ................................................................................45 Konsola R a ils ......................................................................................64 ActiveRecord oraz m o d e le ............................................................... 67 Action C o n tro ller...............................................................................99 W id o k i...............................................................................................105 Rails i A ja x .........................................................................................123 Rou tin g ............................................................................................. 144
3
REST
149
A ctionM ailer.................................................................................... 155 Usługi sie cio w e ................................................................................ 159 Logow anie........................................................................................ 165 ActiveResource................................................................................ 169 D od atki.............................................................................................. 171 C apistrano......................................................................................... 171 TextM ate...........................................................................................179 Metody p om ocn icze........................................................................ 181 S ko ro w id z.........................................................................................153
4
|
Rails. Leksykon kie szo n ko w y
Rails Leksykon kieszonkowy
Przedmowa Ruby on Rails (w skrócie RoR) jest platformą aplikacji webowych napisaną w języku Ruby (http://www.ruby-lang.org) pozwalającą programistom na tworzenie w sposób niewiarygodnie prosty i szybki aplikacji webowych opartych na bazach danych. Platforma ta została napisana przez Davida Heinemeiera Hanssona (DHH), który przy okazji pracy dla 37signals.com stworzył narzędzie o na zwie Basecamp (http://www.basecamphq.com). Przy okazji ekstrakcji kodu aplikacji Basecamp na potrzeby innego programu w lutym 2004 roku DHH postanowił stworzyć Rails i udostępnić jako projekt na licencji open source. Rails wykorzystuje architekturę MVC (Model-View-Controller model-widok-kontroler) roz dzielającą dane (model) od interfejsu (widok) za pomocą kon trolera (służącego do dostępu do danych oraz logiki biznesowej). Więcej informacji na ten temat można znaleźć pod adresem http://www.rubyonrails.org.
Konwencje wykorzystywane w książce W niniejszej książce zastosowano następujące konwencje: Kursywa Oznacza nowe pojęcia, adresy URL, adresy e-mail oraz nazwy i rozszerzenia plików.
5
Czcionka o stałej szerokości
Służy do oznaczania listingów programów, a w akapitach tekstu elementów programów, takich jak nazwy zmiennych czy funkcji, opcji, baz danych, typów danych, zmiennych środowiskowych, instrukcji oraz słów kluczowych. Pogrubiona czcionka o stałej szerokości
Oznacza tekst, na przykład instrukcji, który powinien być dosłownie wpisany przez użytkownika. Pochyła czcionka o stałej szerokości
Oznacza tekst, który powinien być zastąpiony przez podane przez użytkownika wartości lub przez wartości wynikające z kontekstu.
Wykorzystywanie fragmentów kodu Książka ta ma na celu pomoc w wykonaniu pracy. Ogólnie rzecz biorąc, można wykorzystywać kod z książki w swoich programach i dokumentacji. Nie ma potrzeby kontaktowania się z nami w sprawie uzyskania na to zgody, chyba że kopiuje się znaczącą część kodu. Przykładowo napisanie programu, który używa kilku fragmentów kodu z tej książki, nie wymaga uzyskania zgody. Sprzedaż lub dystrybucja przykładów z książek wydawnictw O'Reilly i Helion na nośniku CD-ROM wymaga zgody. Udzielanie odpowiedzi poprzez zacytowanie książki i fragmentu kodu nie wymaga akceptacji. Włączenie znaczącej części przykładowego kodu z tej książki do dokumentacji własnego produktu wymaga jej. Doceniamy cytowanie z podaniem źródła, choć go nie wymagamy. Podanie źródła zazwyczaj obejmuje tytuł, autora, wydawcę i numer ISBN. Na przykład: Rails. Leksykon kieszonkowy, Eric Berry, Helion 2009, ISBN 978-83-246-2136-6. W razie przypuszczeń, że zamiar wykorzystania przykładów z książki wykracza poza dozwolony zakres podany tutaj, prosimy o kontakt pod adresem e-mail [email protected].
6
|
Rails. Leksykon kie szo n ko w y
Podziękowania Książkę tę dedykuję wszystkim osobom piszącym kod Rails i zgłaszającym swoje poprawki oraz autorom blogów wszyst kim osobom, które przyczyniają się do rozwoju najlepszej i najfaj niejszej platformy, jaka kiedykolwiek powstała. Chcę podziękować Ryanowi Batesowi za jego bezcenne podcasty z serii Railscasts (http://railscasts.com), które w ostatnim roku pełniły rolę mojego prywatnego nauczyciela. Dziękuję Greggowi Pollackowi (http://ivww. railsenvy.com) za pomoc w ulepszeniu materiałów do niniejszej książki. Chciałbym także podziękować Ryanowi Daigle (http://www. ryandaigle.com), który dostarcza społeczności Rails najświeższe i najciekawsze wiadomości oraz udostępnił mi świetne materiały i przykłady. Chciałbym podziękować wszystkim osobom, które napisały jakiekolwiek książki techniczne na temat języka Ruby oraz Rails. Wiem już, że jest to o wiele trudniejsze, niż mi się wcześniej wydawało. Chciałbym podziękować Simonowi St. Laurentowi za danie szansy początkującemu pisarzowi, kiedy pod ręką jest tylu o wiele bardziej doświadczonych autorów. Dziękuję także Loranah Dimant za jej czujność i doskonałe rady przy okazji przygotowywa nia tej książki do druku. Chciałbym podziękować mojej przepięknej żonie, Aubree, za zgodę na poświęcenie późnych wieczorów i weekendów na pracę nad książką. Dziękuję, kochanie! Przede wszystkim jednak chciałbym podziękować Michaelowi Fitzgeraldowi. To Ty byłeś powodem, dla którego w ogóle mogłem napisać tę książkę. Byłeś dla mnie niesamowitym źródłem inspiracji, doskonałym nauczycielem i świetnym przyjacielem. Dziękuję.
P o d zię ko w an ia
|
7
Informacje o książce Używam Ruby on Rails mniej więcej od półtora roku nie jest to długo w porównaniu z niektórymi moimi kolegami. W miarę wzrostu mojej pasji dla tej platformy oraz języka, wzrósł także mój apetyt na wiedzę. Aktualnie posiadam jakieś 12 książek na temat Ruby on Rails oraz języka Ruby i uznałem, że przydałby się jakiś poręczny leksykon na temat Ruby on Rails. Książka ta nie zawiera nowych informacji, które nie byłyby łatwo dostępne w Internecie czy innych pozycjach drukowanych. Nie ma na celu przedstawienia języka czy platformy w nowym świetle. Jest po prostu moją próbą zebrania maksymalnie dużej liczby informacji, które mogą się przydać programiście Rails takiemu jak ja w jego codziennej pracy. Duża część książki zawiera dokumentację Rails udostępnianą przez społeczność Rails wraz z dopiskami oraz przykładami pochodzącymi ode mnie bądź od innych osób.
Początki By sprawdzić, czy Rails działa na danym komputerze, należy w powłoce lub wierszu poleceń wpisać następujące polecenie: rails --version
Pozytywna odpowiedź powinna przypominać poniższą (to przykład dla Rails 2.1.0 w systemie operacyjnym Mac OS X): Rails 2.1.0
RubyGems RubyGems to menedżer pakietów dla języka Ruby (http://rubygems. rubyforge.org). Został napisany przez Jima Weiricha (http://onestep back.org). Instaluje pakiety programów języka Ruby, takie jak Rails, i uaktualnia je. Jest dość łatwy do opanowania oraz użycia, łatw iejszy naw et niż tar z systemów Unix czy Linux
8
|
Rails. Leksykon kie szo n ko w y
(,http://www.gnu.org/software/tar) bądź/ar dla języka Java (http://ja.va. sun.eom/j2se/l .5.0/docs/tooldocs/windows/jar.html). Po więcej informacji na ten temat można sięgnąć do dokumentacji RubyGems znajdującej się na stronie http://docs.rubygems.org. Przewodnik RubyGems User Guide (http://docs.rubygems.org/read/ book/1) udostępnia większość informacji na temat RubyGems, jakie będą nam potrzebne. Dostępny jest również indeks poleceń RubyGems (http:lldocs.rubygems.org/readlbookl2).
Instalowanie Rails za pomocą RubyGems RubyGems instaluje się razem z językiem Ruby, jeśli jednak ktoś chciałby uzyskać więcej informacji na ten temat, może zajrzeć do trzeciego rozdziału przewodnika RubyGems User Guide, w którym znajdują się pełne informacje na temat instalacji (http://rubygems. org/read/chapter/3). By sprawdzić, jaka wersja RubyGems zainstalowana jest na na szym komputerze, można użyć polecenia: gem --version
By uzyskać pomoc w korzystaniu z RubyGems, można spróbować: gem --help
By zobaczyć listę poleceń RubyGems, należy wpisać: gem help commands
By wyświetlić przykładowe polecenia z opisami, należy wpisać: gem help examples
By uzyskać pomoc dotyczącą określonego polecenia, należy wpisać: gem help Ipolecenie^i
By zainstalować lub zaktualizować Rails (polecenie su do z systemu Linux wymaga podania hasła administratora), należy wpisać: sudo gem install rails
RubyG em s
|
9
Wykorzystywanie Instant Rails w systemie Windows Instant Rails to rozwiązanie przeznaczone dla systemu Windows, służące do uruchomienia Ruby on Rails z serwerem Apache oraz bazą danych MySQL. Dzięki Instant Rails można z łatwością skonfigurować katalog główny Rails i uruchomić platformę. Nie ma konieczności modyfikacji zmiennych środowiskowych. By zainstalować Instant Rails i utworzyć aplikację o nazwie myapp, wystarczy wykonać poniższe kroki: 1. Należy pobrać i rozpakować Instant Rails ze strony http://ruby forge.org/projects/instantrails. 1. Należy upewnić się, że w ścieżce instalacyjnej nie ma spacji, i uruchomić InstallRails.exe. 3. Instant Rails wykryje, że jest uruchamiany z nowego ka talogu, i zapyta, czy chcemy odtworzyć pliki konfiguracyjne. Należy kliknąć OK. 4. Należy kliknąć przycisk I w celu rozwinięcia menu i wybrać Rails Applications/Manage Rails Applications.... 5. W edytorze, który się otworzy, należy kliknąć przycisk Create New Rails A pp.... 6 .Otworzy się konsola. Należy wpisać rails myapp. 7. Teraz należy zamknąć okno Rails Configuration i otworzyć je ponownie zgodnie z krokiem 4. 8. Na liście aplikacji Rails zobaczymy już myapp. Należy za znaczyć pole wyboru obok tej aplikacji, a następnie kliknąć Start with Mongrel. 9. Teraz trzeba przejść do przeglądarki i wpisać adres http://127.0. 0.1:3000. 10. Witamy na pokładzie!
10
|
Rails. Leksykon kie szo n ko w y
Zależności gemów Zależności gemów zostały dodane w Rails 2.1. Oznacza to, że wymagane gemy można teraz podać w pliku config/environment.rb i zostaną one załadowane automatycznie, kiedy aplikacja zostanie uruchomiona. Na przykład: R a i l s ::I n it ia li ze r.run do
config
# Podanie gemów, o d których uzależniona je s t aplikacja. # Można j e następnie zainstalować za p om ocą "rake gems:install" w nowych instalacjach.
c o n f i g .gem "b j " config.gem "hpricot", ¡version > '0.6', h t t p :/ / c o d e .w h yt he luckystiff .net" config.gem "aws-s3", ¡lib > "aws/s3"
¡source
>
end
Poza tym istnieje również zadanie rake, które instaluje wszystkie config .gems w docelowym systemie: rake gems:install
Jeśli chcemy umieścić gemy w źródle aplikacji, można to zrobić za pomocą zadania gems: unpack: # R ozpakow an ie wszystkich gem ów d o katalogu vendor/gem s
rake gems:unpacl<
Możliwe jest również rozpakowanie pojedynczych gemów: # R ozpakow an ie tylko g em a aws - s 3 d o katalogu vendor/gem s
rake gems:unpack GEM aws-s3
Powyższe polecenie rozpakuje gema do katalogu vendor/gems/ aws-s3-x.x.x, który jest przeszukiwany automatycznie jako część uruchomienia config.gem. By zbudować gema z natywnym rozszerzeniem, można użyć zadania gems: build: rake gems:build # Lub by zbu dow ać ok reślon eg o gem a
rake gems:build GEM aws-s3
RubyG em s
|
11
Polecenia oraz konfiguracja Rails Po zainstalowaniu Rails można użyć polecenia rails do gene rowania nowych aplikacji Rails z domyślną strukturą katalogów oraz konfiguracją dla określonej ścieżki. By utworzyć aplikację Rails o nazwie myapp, należy wpisać: rails myapp
Po wykonaniu tego polecenia zobaczymy listę katalogów oraz plików wygenerowanych przez nie. To nasza aplikacja Rails; myapp będzie folderem głównym, inaczej RAILS ROOT.
Użycie oraz opcje Pomoc dla polecenia rails można uzyskać za pomocą: rails --help
Użycie rails [/ścieżka/do/aplikacji][opcje]
Opcje r,
ruby ścieżka
Ścieżka do wybranych plików binarnych języka Ruby. d,
database nazwa
Konfiguracja dla określonej bazy danych (na przykład mysql, oracle, postgresql, sqlite2, sqlite3). f,
freeze
Zamrożenie Rails w katalogu vendor/rails z gemów ge nerujących szkielet. v,
version
Pokazuje numer wersji Rails i kończy działanie.
12
|
Rails. Leksykon kie szo n ko w y
p,
pretend
Jest wykonywane, ale nie wprowadza żadnych zmian, force
Nadpisuje istniejące pliki. s,
skip
Pomija istniejące pliki. q,
quiet
Blokuje wyświetlanie normalnych danych wyjściowych. t,
backtrace
Debugowanie; w przypadku błędów pokazuje ślad wyko nanych czynności. c,
svn
Modyfikuje pliki z użyciem Subversion (sv n musi być w ścieżce).
Struktura plików Rails Po wygenerowaniu aplikacji Rails utworzone zostają domyślny katalog oraz struktura plików (tabela 1.1). Tabela 1.1. Struktura plików aplikacji Rails Ścieżka
O pis
app
Przechowuje kod specyficzny dla określonej aplikacji.
app/controllers
Przechow uje kontrolery, które dla au to m atycznego odwzorowania adresów URL powinny mieć nazw y takie jak user controUer.rb. W szystkie kontrolery powinny pochodzić od ApplicationController, który z kolei pochodzi od A c ti on Co nt ro ll er::B a s e .
app/m odels
Przechowuje modele, które powinny nosić nazwy takie jak product.rb. Większość modeli pochodzi od ActiveRecord: :Base.
app/view s
Przechowuje pliki szablonów dla widoków. Powinny one nosić ustandaryzowane nazwy, takie jak users/index.html.erb w przypadku akcji UsersController index. W szystkie widoki w ykorzystują składnię eRuby.
Polecenia o raz ko n figu racja Rails
|
13
Tabela 1.1. Struktura plików aplikacji Rails Ścieżka
ciąg dalszy
O pis
ap p /view s/
Przechowuje pliki szablonów dla układów dokumentów, jakie mają
layouts
być wykorzystane z widokami. Przypomina to metodę wspólnego nagłówka czy stopki opakowujących widoki. W widokach definiuje się układ dokumentu za pomocą układu : d e f a u l t
I tworzy plik
o nazwie default.html.erb. Wewnątrz default html.erb wywołuje się <% y i e l d %> w celu w ygenerow ania w idoku z użyciem określonego układu dokumentu. app/helpers
Przechowuje metody pomocnicze, które powinny nosić nazwy takie jak users helper rb. Są one generowane automatycznie, kiedy dla kontrolerów wykorzystuje się polecenie s c r i p t / g e n e r a t e . M etody pom ocnicze m ożna w yko rzysta ć do opakow ania funkcjonalności przeznaczonej dla widoków w metody.
config
Pliki konfiguracyjne dla środowiska Rails, mapy tras, bazy danych oraz Innych zależności.
db
Zawiera schemat bazy danych znajdujący się w sch em a .rb.d b /
doc
W tym katalogu przechowywana będzie dokumentacja aplikacji po jej wygenerowaniu za pomocą r a k e doc : a p p .
m igrate. Zawiera wszystkie sekwencje migracji dla schematu.
llb
Biblioteki specyficzne dla aplikacji. Tak naprawdę każdy rodzaj własnego kodu, który nie jest kontrolerem, modelem ani metodą pomocniczą. Katalog ten znajduje się w ścieżce ładowania.
public
Katalog dostępny dla serwera W W W . Zawiera podkatalogi przeznaczone dla obrazków, arkuszy stylów oraz skryptów JavaScrlpt. Zawiera również dyspozytor (ang. dispatcher) I domyślne pliki HTM L. Powinien być ustawiony jako D OCUM ENTROO T serwera WWW.
script
Skrypty pomocnicze służące do automatyzacji oraz generacji.
test
Testy jednostkowe oraz funkcjonalne w raz z flksturaml. Kiedy wykorzystuje się skrypty s c r i p t / g e n e r a t e , pliki szablonów testów zostają dla nas wygenerowane I umieszczone w tym katalogu.
vendor
Biblioteki zewnętrzne, od których uzależniona jest nasza aplikacja. Zawiera również podkatalog plugins. Katalog ten znajduje się w ścieżce ładowania.
14
|
Rails. Leksykon kie szo n ko w y
Konfiguracja Rails Każda aplikacja Rails oparta jest na plikach konfiguracyjnych określających jej sposób działania. Pliki te znajdują się w folderze config: boot.rb Ładuje plik programu rozruchowego. Zazwyczaj plik ten nie musi być modyfikowany. routes.rb Plik konfiguracyjny określający trasy. environment.rb Ogólne ustawienia konfiguracyjne dla aplikacji Rails. environments/development.rb Konfiguracja specyficzna dla środowiska programistycznego. environments/test.rb Konfiguracja specyficzna dla środowiska testowego. environments/production.rb Konfiguracja specyficzna dla środowiska produkcyjnego. database.yml Konfiguracja połączenia z bazą danych. initializers/inflections.rb Dodaje nowe reguły fleksyjne do aplikacji (na przykład dotyczące liczby mnogiej, pojedynczej, rzeczowników nie policzalnych). initializers/mime types.rb Dodaje nowe typy MIME do użycia w blokach respond to (na przykład rtf lub iPhone). initializers/new rails defaults.rb Te ustawienia zmieniają zachowanie aplikacji Rails 2 i będą domyślne dla Rails 3. Plik ten w Rails 3 stanie się przestarzały.
Polecenia o raz ko n figu racja Rails
|
15
Więcej informacji na temat konfiguracji tras, środowisk oraz baz danych można znaleźć w odpowiednich częściach niniejszej książki.
Skrypty Rails zawiera skrypty pomocnicze służące do automatyzacji oraz generowania kodu. Wykorzystując te skrypty, programiści mogą szybko budować aplikacje, zachowując jednocześnie kontrolę nad wygenerowaną zawartością.
script/about Wyświetla informacje o środowisku aplikacji: Ruby version RubyCems version Rails version Active Record version Action Pack version Active Resource version Action Mailer version Active Support version Application root Environment Database adapter Database schema version
script/console Konsola daje nam dostęp do środowiska Rails, w którym można wykonywać interakcje z modelem domeny. Wszystkie części aplikacji są tutaj skonfigurowane w taki sposób, jakby aplikacja działała. Można badać modele domeny, zmieniać wartości i zapisy wać do bazy danych. Konsolę można uruchomić za pomocą poniższego skryptu: ./script/console
16
|
Rails. Leksykon kie szo n ko w y
Uruchomienie konsoli bez argumentów spowoduje jej działanie z wykorzystaniem środowiska programistycznego. By zatrzymać konsolę, należy wpisać: quit lub exit
W późniejszych wersjach Rails można przeładowywać modele oraz kontrolery za pomocą poniższego polecenia: reload!
By przywrócić aplikację do pierwotnych wartości, należy wpisać: Di sp a t c h e r .reset application!
Użycie ./script/console [środow is ko] [opcje]
Opcje s,
sandbox
Przy wyjściu przywraca modyfikacje bazy danych do stanu początkowego. irb [irb]
Uruchamia inny irb. Wskazówka Wykorzystywanie konsoli w trybie sandbox daje programiście Rails ogromne możliwości. Jeśli na przykład utworzymy skrypt uaktualniający wszystkie wiersze tabeli, możemy najpierw uruchomić ten skrypt testowo, w trybie sandbox, w oparciu o istniejące dane, a później sprawdzić, czy zmiany zostały przeprowadzone w poprawny sposób. Jeśli coś pójdzie nie tak, wystarczy wyjść z konsoli, a w bazie danych nie zostaną wprowadzone żadne zmiany.
Polecenia o raz ko n figu racja Rails
|
17
script/destroy Skrypt ten zniszczy wszystkie pliki utworzone przez odpowiadające mu polecenie script/generate. Przykładowo polecenie script/ ^d es tr oy migration CreatePost usunie odpowiedni plik ### create post.rb znajdujący się w katalogu db/migrate, natomiast polecenie script/destroy scaffold Post usunie kontroler oraz widoki dla Post wraz z modelem i migracją oraz wszystkimi powiązanymi testami, a także wiersz map. resources :post w pliku config/routes.rb. Użycie ./script/destroy generator [opcje] [ar gumenty]
app/helpers/products helper.rb test/functional/products controller test.rb app/controllers/products c o n t r o U e r . r b test/functional test app/views/products app/views app app/helpers app app/controllers app
script/generate Generatory wykorzystywane są do tworzenia kodu służącego do natychmiastowego użycia w aplikacji Rails. Po uruchomieniu generatora (za pomocą script/generate) nowe pliki (kontrolery, modele, widoki) są generowane i dodawane do aplikacji. Możliwe
18
|
Rails. Leksykon kie szo n ko w y
jest również tworzenie własnych generatorów. Więcej informacji na temat własnych generatorów można znaleźć w podcaście Ryana Batesa znajdującym się pod adresem http://railscasts.com/episodes/58. By otrzymać pomoc dotyczącą skryptu generatora, należy wpisać: ./script/generate --help
Pomoc na temat konkretnego generatora można uzyskać, wpisując: ./script/generate Igenerator^i --help
Rails zawiera kilka wbudowanych generatorów. controller
Tworzy nowy kontroler wraz z widokami. Jako argumenty należy przekazać nazwę kontrolera, albo w pisowni wielbłądziej, albo ze znakiem _, a także listę widoków. By utworzyć nowy kontroler wewnątrz modułu, należy podać nazwę kontrolera w postaci ścieżki, na przykład nazwa modułu/ nazwa kontrolera. Można również tworzyć podkontrolery dziedziczące po kontrolerze nadrzędnym, podając nazwę kontrolera w postaci NazwaKontrolera '-»■Nadrzędnego: :NazwaKontroleraPodrzędnego. Jeśli na przykład mamy kontroler o nazwie admin i chcemy utworzyć podkontroler o nazwie users dziedziczący filtr uwierzytelniający po kontrolerze nadrzędnym AdminController, możemy wpisać: ./script/generate controller Admin::Users
Powyższy kod generuje klasę kontrolera w app/controllers/admin, szablony widoku w app/views/admin/controller name, klasę pomoc niczą w app/helpers/admin i zbiór testów funkcjonalnych w test/ functional/admin.
Polecenia o raz ko n figu racja Rails
|
19
By kontroler potomny UsersController dziedziczył po Admin ^Controller, będziemy musieli dodać poprawne dziedziczenie
w pliku app/controllers/admin/users controller.rb. class UsersController < AdminController
Przykład ./script/generate controller Product name:string p r i c e :decimal quantity:integer
integration test
Tworzy nowy test integracyjny. Jako argument należy przekazać nazwę testu, albo w pisowni wielbłądziej, albo ze znakiem Nowa klasa testowa zostanie wygenerowana w test/integration/nazwa testu test.rb. Użycie ./script/generate integration test NazwaTestuIntegracyjnego opcje]
Przykład ./script/generate integration test GeneralStories
mailer
Tworzy nowy program pocztowy (mailer) wraz z widokami. Jako argumenty należy przekazać nazwę programu pocztowego, albo w pisowni wielbłądziej, albo ze znakiem _, oraz opcjonalną listę e-maili jako argumenty. Powoduje to wygenerowanie klasy programu pocztowego w app/ models, szablonów widoków w app/views/nazwa programu, testów jednostkowych w test/unit oraz fikstur w test/fixtures.
Przykład ./script/generate mailer Notifications signup e*forgot password invoice
migration
Tworzy nową migrację bazy danych. Jako argumenty należy przekazać nazwę migracji, albo w pisowni wielbłądziej, albo ze znakiem _, oraz opcjonalną listę par atrybutów. Klasa migracji generowana jest w db/migrate i poprzedzona jest datą. Migrację można nazwać w dowolny sposób. Preferowanym standar dem jest jednak nazwa szczegółowo opisująca cel skryptu, na przykład AddColumnsToTable czy RemoveColumnsFromTable. Użycie ./script/generate migration NazwaMigracji [opcje]
Przykład ./script/generate migration AddLastLoginToUsers ‘’►last login :datetime
model
Tworzy nowy model, generując nową klasę w app/models, nową klasę migracji w db/migrate, test jednostkowy w test/unit oraz fiksturę w test/fixtures. Jako argumenty należy przekazać nazwę modelu, albo w pisowni wielbłądziej, albo ze znakiem _, oraz opcjonalną li stę par atrybutów. Użycie ./script/generate model NazwaModelu [pole'.typ, pole'.typ]
Polecenia o raz ko n figu racja Rails
|
21
Przykład ./script/generate model Book title:string description :text ^ p a g e s :integer
observer
Tworzy nową klasę Observer. Observer umożliwia monitorowanie zdarzeń cyklu życia obiektu modelu poza samym modelem, a także pozwala na uniknięcie obciążenia klasy modelu logiką niestanowiącą jej jądra. Więcej informacji na temat tej klasy można znaleźć pod adresem http://api.rubyonmils.org/classes/ActweRecord/Observer.html. By wygenerować nowy obiekt Observer, należy jako argument przekazać jego nazwę, albo w pisowni wielbłądziej, albo ze znakiem . Generator tworzy klasę Observer w katalogu app/models oraz test jednostkowy w katalogu test/unit. Użycie ./script/generate observer NazwaKlasyObserver [opcje]
Przykład ./script/generate observer Account
plugin
Tworzy nowy dodatek (plugin). Jako argument należy przekazać nazwę dodatku, albo w pisowni wielbłądziej, albo ze znakiem By dodać również generator przykładów, należy przekazać opcję with generator.
Tworzy dodatek w katalogu vendor/plugins wraz z plikiem init.rb oraz README i standardowe katalogi lib, task oraz test. Użycie ./script/generate plugin NazwaDodatku [opcje]
22
|
Rails. Leksykon kie szo n ko w y
Przykład ./script/generate plugin SimpleLayout
resource
Tworzy nowy zasób wraz z pustym modelem oraz kontrolerem przystosowanym do potrzeb aplikacji REST zorientowanej na zaso by. Należy przekazać pojedynczą nazwę modelu, albo w pisowni wielbłądziej, albo ze znakiem _, jako pierwszy argument oraz opcjonalną listę par atrybutów. Użycie ./script/generate resource NazwaModelu [pole: typ, pole: typ]
Przykład ./script/generate resource Post title:string body:text ‘»published: boolean
scaffold
Tworzy rusztowanie (ang. scaffold) całego zasobu, od modelu oraz migracji po kontroler i widoki, wraz z pełnym zestawem testów, i dodaje zasób do pliku config/routes.rb. Zasób jest gotowy do użycia jako punkt wyjścia dla aplikacji REST zorientowanej na zasoby. Użycie ./script/generate scaffold NazwaModelu [pole: typ, pole: typ]
Przykład ./script/generate scaffold Comment user id:integer body:text
session migration
Tworzy migrację dodającą tabelę sesji wykorzystywaną przez maga zyn sesji ActiveRecord. Jako argument należy przekazać nazwę migracji, albo w pisowni wielbłądziej, albo ze znakiem
Przykład ./script/generate session migration CreateSessionTable
Więcej informacji na temat różnych typów sesji można znaleźć w podrozdziale „Sesje" w dalszej części książki.
script/performance Rails zawiera kilka skryptów poprawiających wydajność aplikacji, benchmarker
Testuje kilka razy wydajność jednej lub większej liczby instrukcji w środowisku Rails. Użycie ./script/performance/benchmarker [razy][skrypt][skrypt] ‘HIskrypt]. . .
Przykład ./script/performance/benchmarker 5 'Person.do t h i s 1 'Person, ‘’►do that'
profiler
Profiluje pojedynczą instrukcję w środowisku. Użycie ./script/performance/profiler l s kryp t]l ra zy ]l'fl at|g r a p h | ‘►graph html]
Przykład ./script/performance/profiler 'Person.do t h i s (10)'
24
|
Rails. Leksykon kie szo n ko w y
25 graph
request
Skrypt opakowujący bibliotekę ruby-prof (http://ruby-prof.rubyforge. org). Skrypt ten pozwala wykonać większą liczbę żądań dla ad resu URI w aplikacji i otrzymać szczegółowy raport profilu kodu w wersji tekstowej oraz HTML. Użycie ./script/performance/request lopcj e^lścieźka sk ry pt u]
Opcje n,
times [0000]
Określa, ile żądań należy przetworzyć (wartością domyślną jest 100). b,
benchmark
Test wydajności zamiast profilowania. open [p o le c e n ie l
Polecenie otwarcia wyników profilowania (wartością domyśl ną jest „open %s &"). Przykład # Utworzenie pliku o nazw ie 'perfscript' za w ierająceg o
p o st (1/sessions1, { :login
> 'berry1, ¡password
> 'test'
})
# Wyniki Thread ID: 218880 Total: 21.S39S47 %self 19.28
script/process Skrypty te służą do badania procesów oraz pomagają w ich kontrolowaniu. inspector
Wyświetla informacje systemowe dotyczące dyspozytorów Rails (lub innych procesów wykorzystujących pliki pici) za pomocą polecenia ps. Użycie ./script/process/inspector [opcje]
Opcje s,
ps p o le c e n ie Domyślnie: ps o p id , s t a t e , u ser, s t a r t , tim e, pcpu, vsz, '-*majplt, command p %s.
p,
pidpath ś c ie ż k a Domyślnie: Ąlsers/berry/Sites/clearplay/tmp/pids.
r,
pattern w zorzec Domyślnie: dispatch.*.pid.
Przykład # w łasny ps, %s to gd zie p i d s ię p rzep lata
inspector -s 1ps -o u s e r ,s t a r t ,m a j f l t ,p c p u ,vsz -p % s 1
reaper
Skrypt reaper służy do ponownego uruchomienia, przeładowania, zwykłego zakończenia oraz zakończenia wymuszonego procesów wykonujących dyspozytor Rails (lub innych procesów odpowiadają cych na te same sygnały). Najczęściej robi się to, kiedy dostępna jest nowa wersja aplikacji, by można było uaktualnić istniejące procesy tak, by wykorzystywały one najnowszą wersję kodu.
Polecenia o raz ko n figu racja Rails
|
27
Skrypt ten wykorzystuje pliki pid do pracy z procesami i domyślnie zakłada, że znajdują się one w katalogu RAILS ROOT/tmp/pids. Akcje skryptu reaper są następujące: restart
Ponownie uruchamia aplikację, przeładowując kod aplikacji oraz platformy. reload
Przeładowuje jedynie aplikację, ale nie platformę (na przykład środowisko programistyczne). graceful
Oznacza wszystkie procesy jako kandydatów do zakończenia po kolejnym żądaniu. kill
Wymusza zakończenie wszystkich procesów bez względu na to, czy akurat obsługują jakieś żądania. Użycie ./script/process/reaper [opcje]
Opcje a,
action nazwa reload I graceful I kill (domyślnie: restart).
p,
pidpath ścieżka
Domyślnie: [RAILS ROOT]/tmp/pids. r,
pattern wzorzec
Domyślnie: dispatch.[0-9]*.pid. Przykład # Wymuszone zakończenie wszystkich procesów przechowujących pliki p id w katalogu tmp/pids
reaper -a kill -r *.pid
28
|
Rails. Leksykon kie szo n ko w y
spaw ner
Skrypt spawner opakowuje spawn-fcgi oraz Mongrel i ułatwia uruchamianie większej liczby procesów wykonujących dyspozytor Rails. Polecenie spawn fcgi pochodzi z serwera lighttpd, jednak można je wykorzystać zarówno w lighttpd, jak i Apache (i dowol nym innym serwerze WWW obsługującym zarządzane zewnętrz nie procesy FCGI). Mongrel jest zawarty automatycznie w mongrel_ t r a i l s w celu uruchamiania dyspozytorów. Użycie ./script/process/spawner [ p l a t f o r ma ] [ o p c j e]
Opcje a,
address ip Wiązanie do adresu IP (domyślnie: 0 .0 .0 .0 ) .
p,
port numer N u m er p o rtu p oczątk o w ego (dom yślnie: 8000).
i,
instances lic z b a Liczba instancji (dom yślnie: 3).
r,
repeat sekundy Powtarza próbę wykonania skryptu co n sekund (domyślnie: wyłączone).
e,
environment nazwa test I development I production (domyślnie: production).
P,
prefix ś c ie ż k a Adres URL przedrostka dla aplikacji Rails (wykorzystywany jedynie w serwerze Mongrel w wersji 0.3.15 oraz wyższej).
n,
process nazwa Domyślnie: dispatch.
Polecenia o raz ko n figu racja Rails
|
29
s,
spawn er ścieżka
Domyślnie: /usr/bin/env spawnfcgi (dla instalacji w systemie Mac OS X). d,
dispatcher ścieżka
Domyślnie: [RAILS ROOT]/public/dispatch.fcgi. Przykład # R ozpoczyna 10 instancji, od liczając o d 9100 d o 9109, w ykorzystując serw er Mongrel, #je ś li je s t on dostępny
./script/process/spawner -p 9100 -i 10
script/runner Wykonuje kod w języku Ruby lub określony plik tego języka. Użycie ./script/runner [opcje]( 'J a k i ś . ko d( Ru by )' lub nazwa p l i k u )
Opcje e,
environment nazwa
Określa środowisko, w jakim ma działać skrypt runner (test, development bądź production). Przykład ./script/runner M o v i e L i s t .update from imdb -e production
Wskazówka Skrypt runner można również wykorzystać do wykonywania kodu języka Ruby w skryptach powłoki: # ! /usr/bin/env/Users/berry/Sites/myapp/script/runner Product,find(:all).each { |p| p.price * 2 ; p.save! }
30
|
Rails. Leksykon kie szo n ko w y
script/server Uruchamia serwer WWW. Jeśli Mongrel jest zainstalowany, do myślnie zostanie uruchomiony. By wymusić użycie webrick, należy przekazać webrick jako opcję. Użycie ./script/server [opcje]
Opcje p,
b,
port port U ru ch am ia Rails n a ok reślon ym p orcie (dom yślnie: 3000). binding ip
Wiąże Rails z określonym adresem IP (domyślnie: 0 .0 .0 .0 ) . d,
daemon
Sprawia, że serwer działa jako daemon. u,
debugger
Włącza debugowanie Ruby dla serwera. e,
environment nazwa
Określa środowisko, w jakim ma działać serwer (test, development bądź production domyślnie development).
Środowiska Środowiska Rails odzwierciedlają etapy tworzenia typowej aplikacji: programowanie, testowanie oraz produkcję. Środowisko Rails można ustawić na jeden lub oba z poniższych sposobów: • ustaw ienie zmiennej środow iskow ej RAILS ENV n a n azw ę środ ow isk a (development, test lub production),
Śro d o w iska
|
31
• zmodyfikowanie pliku config/environment.rb i uaktual nienie wiersza (po upewnieniu się, że nie znajduje się on w komentarzu): E N V [ 1RAILS E N V '] ||
'production
Wewnątrz aplikacji Rails dostęp do nazwy środowiska można uzy skać za pomocą RAILS_ENV. Trzy domyślne środowiska Rails to: Środowisko programistyczne (development) Środowisko programistyczne wykorzystywane jest przede wszystkim przy tworzeniu aplikacji Rails. Kod aplikacji jest przeładowywany przy każdym żądaniu, co spowalnia czas odpowiedzi, ale jest rozwiązaniem idealnym, gdyż programi sta nie musi ponownie uruchamiać serwera po wprowadze niu zmian. Środowisko testowe (te s t) Środowisko testowe służy wyłącznie do wykonywania ze stawu testów aplikacji. Nigdy nie powinno się go używać w innych okolicznościach. Należy pamiętać, że testowa baza danych służy wyłącznie zestawowi testów i jest czyszczona i odtwarzana pomiędzy poszczególnymi uruchomieniami testów. Nie należy polegać na danych tam się znajdujących! Środowisko produkcyjne (production) Środowisko produkcyjne przeznaczone jest dla skończonych, działających aplikacji. Kod nie jest przeładowywany pomiędzy żądaniami, a czas odpowiedzi jest o wiele szybszy niż w trybie programistycznym.
Konfiguracja środowiska Kiedy tworzona jest aplikacja Rails, w folderze config/environments wygenerowane zostają trzy pliki środowiskowe development.rb,
32
|
Rails. Leksykon kie szo n ko w y
test.rb oraz production.rb. Każdy zawiera ustawienia konfiguracyjne dla odpowiadającego mu środowiska. Choć istnieją domyślne ustawienia konfiguracyjne, każdą opcję można zmodyfikować.
Opcje ogólne Przy wykorzystywaniu bloku R a ils : : I n i t i a l i z e r do |config | należy poprzedzić za pomocą c o n fig . każdą z tych opcji. cache_classes Określa, czy klasy powinny być umieszczane w pamięci podręcznej (jeśli klasy mają być przeładowywane z każdym żądaniem, należy opcję tę ustawić na fa ls e ). cont r o l l er_paths Lista ścieżek, które powinny być przeszukiwane pod ką tem lokalizacji kontrolerów (domyślnie app/controllers oraz components). d atabase_config u ration_file Ścieżka do pliku konfiguracyjnego bazy danych, jaki ma być użyty (domyślnie config/database.yml). frameworks Lista komponentów platformy Rails, które powinny zostać załadowane (domyślnie :active_record, :action_controller, : action_view, : action_mailer oraz : action_web_service). load_paths Tablica opcji dodatkowych ścieżek, jakie należy dodać do ścieżki ładowania. Domyślnie wszystkie ścieżki app, lib, vendor oraz mock są zawarte w tej liście. lo g _level Poziom logowania wykorzystywany domyślnie w Rails. W trybie produkcyjnym ma wartość domyślną : info, w trybie programistycznym : de b ug.
Śro d o w iska
|
33
log_path
Ścieżka do pliku z logiem, jaki ma być użyty. Domyślnie log/#{środowisko}.log (na przykład log/development.log lub log/production.log). logger
Określa, z jakiego programu logującego skorzystać. Domyśl nie program logujący zostanie utworzony i zainicjalizowany za pomocą opcji log path oraz log level, jednak programi sta może za pomocą tej opcji ustawić wykorzystywany pro gram logujący w sposób bezpośredni. view_path
Katalog główny widoków aplikacji. Domyślnie app/views. whiny_nils
Opcję tę należy ustawić na true, jeśli chcemy być ostrzegani, kiedy próbujemy wywołać jakąkolwiek metodę dla nil. Stan dardowe zachowanie Ruby można uzyskać, ustawiając false. plugins
Lista dodatków, jakie mają zostać załadowane. Jeśli ustawi się tę opcję na nil, załadowane zostaną wszystkie dodatki. Po ustawieniu na [ ] żadne dodatki nie zostaną załadowane. W przeciwnym razie dodatki zostaną załadowane w okre ślonej kolejności. plugin_paths
Ścieżka do katalogu głównego zawierającego katalogi z do datkami. Domyślnie vendor/plugins. plugin_locators
Klasy odpowiedzialne za odszukanie pożądanych dodatków, które mają być załadowane dla aplikacji. Domyślnie będzie to klasa Rails: :Plugin: :FileSystemLocator odpowiedzialna za znajdowanie dodatków do załadowania w katalogu vendor/ plugins. Lokalizację gema można podać, tworząc klasę pod rzędną Rails: :Plugin : :Locator i dodając tę klasę do listy pługin_locators.
34
|
Rails. Leksykon kie szo n ko w y
plugin_loader
Klasa odpowiedzialna za ładowanie każdego dodatku. Do myślnie będzie to Rails: :Plugin: :Loader, jednak klasa podrzędna mogłaby uzyskać dostęp do bardziej szczegóło wej modyfikacji zachowania ładowania. Więcej informacji na ten temat można znaleźć w implementacji Rails: :Plugin: Loader.
Opcje ActiveRecord Przy wykorzystywaniu bloku Rails::Initializer do |config | należy poprzedzić za pomocą c o n f i g .ac ti v e _ r e c o r d . każdą z tych opcji. primary_key_prefix_type
Akcesor typu przedrostka, jaki zostanie dodany do każdej nazwy kolumny z kluczem pierwotnym. Dostępne opcje to :table_name oraz :table_name_with_underscore. Po wy braniu tej pierwszej możliwości klasa Product będzie szu kała productid zamiast id jako kolumny z kluczem pier wotnym. Należy pamiętać, że jest to ustawienie globalne dla wszystkich ActiveRecords. table_name_prefix
Łańcuch znaków dodawany jako przedrostek do każdej nazwy tabeli. Domyślnie przedrostek ten jest pustym łań cuchem znaków. table_name_suffix To samo co table_name_prefix, jednak dodaje łańcuch
znaków jako przyrostek do nazwy tabeli. pluralize_table_names
Określa, czy nazwy tabel powinny być liczbą mnogą od odpowiedniej nazwy klasy (domyślnie ma wartość true).
Śro d o w iska
|
35
colorize_logging
Określa, czy logi powinny mieć kody kolorów ANSI w in strukcjach (domyślnie ma wartość true). default_timezone
Określa, czy użyć T i m e .local (przy wykorzystaniu : local), czy też Time .utc (przy wykorzystaniu : utc), kiedy pobiera się datę oraz czas z bazy danych (domyślnie ma wartość :local). allow_concurrency
Określa, czy użyć osobnych połączeń dla każdego wątku, czy też jednego współdzielonego połączenia dla wszystkich wąt ków (domyślnie ma wartość false). Przy pisaniu aplikacji wykorzystującej wątki należy opcję tę ustawić na true. schema_format
Określa, czy zrzut bazy danych wykonać w formacie ruby, czy sql. Przybiera wartości :ruby bądź :sql; domyślnie ma wartość :ruby.
Opcje Action View Przy wykorzystywaniu bloku Rails::Initializer do |config | należy poprzedzić za pomocą config.action view. każdą z tych opcji. erb_trim_mode
Określa tryb przycinania dla kompilatora ERB (domyślnie ma wartość „ "). cache_template_loading
Określa, czy wyniki wyszukiwania rozszerzeń plików oraz ścieżek szablonów powinny być umieszczane w pamięci podręcznej. Dla środowiska programistycznego opcja ta powinna mieć wartość false (domyślnie ma wartość true).
36
|
Rails. Leksykon kie szo n ko w y
debug_rj s
Określa, czy odpowiedzi RJS powinny być opakowywane w blok try/catch ostrzegający przed przechwyconym wy jątkiem (a następnie ponownie go zgłaszający).
Opcje ActionMailer Przy wykorzystywaniu bloku Rails::Initializer do |config | należy poprzedzić za pomocą c o n f i g .action mailer. każdą z tych opcji. template_root
Opcja ta określa podstawę, z której będą wykonywane od wołania do szablonów. logger
Program logujący wykorzystywany do generowania infor macji o działaniu poczty elektronicznej, jeśli jest ona dostępna. Opcję tę można ustawić na nil w celu wyłączenia logowania. Program logujący jest zgodny zarówno z własnym progra mem Logger dla Ruby, jak i programami Log4r. smtp_settings
Pozwala na szczegółową konfigurację metody dostarczania poczty elektronicznej :smtp: :address
Pozwala na wykorzystanie zdalnego serwera poczty elektronicznej. Wystarczy zmienić wartość tej opcji na inną od domyślnego ustawienia localhost. :port
W sytuacji gdy serwer poczty elektronicznej działa na porcie innym od 25, zmiany można wprowadzić tutaj. :domain
Jeśli konieczne jest określenie domeny HELO, tutaj można to zrobić.
Śro d o w iska
|
37
:user_name
Jeśli serwer poczty elektronicznej wymaga uwierzytel nienia, należy ustawić nazwę użytkownika w tym łań cuchu znaków. :password
Jeśli serwer poczty elektronicznej wymaga uwierzytel nienia, należy ustawić hasło w tym łańcuchu znaków. :authentication
Jeśli serwer poczty elektronicznej wymaga uwierzytel nienia, tutaj należy podać typ uwierzytelnienia. Do stępne opcje to :plain, :login oraz :cram_md5. sendmail_settings
Pozwala na nadpisanie opcji dla metody dostarczania poczty elektronicznej :sendmail: :location
Lokalizacja pliku wykonywalnego programu sendmail (domyślnie /usr/sbin/sendmail). :arguments
Argumenty wiersza poleceń. raise_delivery_errors
Określa, czy błędy powinny być zgłaszane, jeśli wiadomości e-mail nie zostaną dostarczone. Domyślnie ma wartość true. delivery_method
Definiuje metodę dostarczania poczty elektronicznej. Dostępne wartości to :smtp (wartośćdomyślna), : sendmail oraz :test. perform_deliveries
Określa, czy metody deliver * są w rzeczywistości wyko nywane. Domyślnie tak jest, jednak można to wyłączyć, by ułatwić testy funkcjonalne.
38
|
Rails. Leksykon kie szo n ko w y
deliveries
Przechowuje tablicę wszystkich wiadomości e-mail przesła nych przez ActionMailer za pomocą deliverymethod :test. Najbardziej przydaje się w testach jednostkowych oraz funkcj onalny ch. default_charset
Określa kodowanie znaków dla ciała wiadomości oraz tematu (domyślnie ma wartość utf 8). Można również wybrać inne kodowanie znaków wewnątrz metody za pomocą @charset. default_content_type
Określa typ zawartości wykorzystywany dla głównej części wiadomości (domyślnie ma wartość text /plain). Można rów nież użyć @content_type do wybrania innego typu zawarto ści wewnątrz metody. default_mime_version
Określa wersję MIME wykorzystaną dla wiadomości. Domyśl nie opcja ta ma wartość 1.0. Można również użyć @mime_ ^-»-version do wybrania innej wartości wewnątrz metody. default_implicit_parts_order
Kiedy wiadomość tworzona jest w sposób niejawny (to zna czy poszczególne jej części składane są z szablonów określa jących typ zawartości w swoich nazwach plików), zmienna ta kontroluje, jak uporządkowane są te części. Domyślnie ma wartość [ "text/html", "text/enriched", "text/plain"]. Elementy pojawiające się w tablicy jako pierwsze mają wyż szy priorytet w kliencie poczty elektronicznej i pojawiają się w wiadomości zakodowanej za pomocą MIME na końcu. Można również użyć @implicit_parts_order do wybrania innej kolejności wewnątrz metody.
Śro d o w iska
|
39
Własne środowiska Rails Aplikacje Rails nie są ograniczone do środowiska programistycz nego, testowego oraz produkcyjnego. Z łatwością można tworzyć dowolną liczbę konfiguracji dodatkowych środowisk Rails. Załóżmy, że firma, dla której pracujemy, posiada serwer służący do testów wewnętrznych, będący jednocześnie serwerem lustrza nym (mirrorem) dla prawdziwego serwera produkcyjnego. Być może wolelibyśmy, by pewne elementy aplikacji nie działały na serwerze testowym tak samo jak na produkcyjnym, dlatego do datkowe środowisko może być idealnym rozwiązaniem. By utworzyć nowe środowisko o nazwie staging, należy wykonać następujące kroki: 1. Utworzyć plik config/environments/staging.rb. Będzie on zawie rał konfigurację dla tego środowiska. Można ją skopiować z plików innych środowisk i zmodyfikować zgodnie z po trzebami. 2. Należy dodać staging do pliku config/database.yml z odpowied nimi ustawieniami bazy danych oraz jej nazwą. 3. Należy utworzyć bazę danych i uruchomić skrypty migracji (więcej na ten temat w podrozdziale „Migracje"). Teraz można uruchomić aplikację Rails z nowym środowiskiem.
Rake Rake to narzędzie, które pozwala budować, kompilować i w inny sposób przetwarzać pliki, czasem w dużej ilości. Przypomina na rzędzia Make (http://www.gnu.org/software/make/) oraz Apache Ant (http://ant.apache.org), jednak napisane jest w języku Ruby. Ruby wykorzystuje je w wielu zastosowaniach, nie tylko w Rails, jed nak to operacje Rails bardzo często korzystają z Rake.
40
|
Rails. Leksykon kie szo n ko w y
Rake wykorzystuje Rakefile do dowiedzenia się, co należy zrobić. Rakefile zawiera nazwane zadania. Kiedy tworzy się projekt Rails, Rakefile tworzony jest automatycznie, by pomóc nam poradzić sobie z różnymi zadaniami, takimi jak wykonywanie testów, prze glądanie statystyk projektu oraz migracja schematów bazy danych. Narzędzie Rake napisane zostało przez Jima Weiricha (http://onestep back.org/). Dokumentację Rake można znaleźć pod adresem http:// rake.rubyforge.org/. Dobre wprowadzenie do tego narzędzia autor stwa Martina Fowlera znajduje się na stronie http://www.martin fowler.com/articles/rake.html. By sprawdzić, czy Rake znajduje się na naszym komputerze, należy wpisać: rake --version
Odpowiedź twierdząca powinna przypominać poniższą: r a k e , version 0.8.1
Jeśli nie otrzymamy odpowiedzi twierdzącej, należy wykorzystać RubyGems do zainstalowania Rake: sudo gem install rake
Pomoc dotyczącą Rake można otrzymać, wpisując: rake --help
By zobaczyć dostępną listę zadań Rake, należy wpisać: rake --tasks
By zobaczyć statystyki projektu dla aplikacji Rails, należy w folde rze głównym aplikacji wpisać: rake stats
By użyć najnowszej, programistycznej wersji Rails, znanej jako EdgeRails, należy wpisać: rake r a i l s :f r e e z e :edge
Rake
|
41
Alternatywnie można dokonać zamrożenia dowolnej wcześniej szej wersji Rails. rake r a i l s :f r e e z e :edge TAC rei 2-0-2
By dokonać odmrożenia Rails i skorzystać z domyślnej instalacji systemu, można wpisać: rake r a i l s :uirfreeze
Użycie i opcje Użycie rake [-f rakefile] {opcje} p o l e c e n i a ...
Opcje C,
classic namespace
Umieszcza Task oraz FileTask w przestrzeni nazw najwyższe go poziomu. D,
describe
Opisuje zadania (dopasowując opcjonalny wzorzec PATTERŃ), a następnie kończy działanie. n,
dry run
Uruchamiane „na sucho", bez wykonywania działań. h,
help
Wyświetla tę listę opcji. I,
libdir LIBDIR
Uwzględnia katalog biblioteki LIBDIR w ścieżce wyszukiwania dla wymaganych modułów. N,
nosearch
Nie szuka Rakefile w katalogach nadrzędnych.
42
|
Rails. Leksykon kie szo n ko w y
P,
prereqs
Wyświetla zadania i zależności, a następnie kończy działanie. q,
quiet
Nie loguje komunikatów w standardowym wyjściu. f,
rakefile
Wykorzystuje plik FILE jako Rakefile. R,
rakelibdir RAKELIBDIR
Automatycznie importuje wszystkie pliki .ra te znajdujące się w katalogu bibliotek Rake RAKELIBDIR (domyślnie ma wartość rakelib). r,
require MODULE
Przed wykonaniem Rakefile wymagany jest moduł MODULE. s,
silent
Podobne do w katalogu. T,
quiet, jednak zatrzymuje również ogłoszenie
tasks
Wyświetla zadania (odpowiadające opcjonalnemu wzorcowi PATTERN) z opisami, a następnie kończy działanie. t,
trace
Włącza śledzenie wywoływania i wykonywania oraz pełny ślad wykonanych czynności. v,
verbose
Loguje komunikaty w standardowym wyjściu (wartość domyślna). V,
version
Wyświetla zainstalowaną wersję Rake.
Budowanie własnych zadań Rake Czasami tworzy się własne zadania Rake, które wykonują działa nia, jakich nie wykonują zadania domyślne.
Rake
|
43
Jako przykład utwórzmy zadanie Rake odnajdujące użytkowników, których subskrypcje niedługo wygasną, i wysyłające do nich wia domość e-mail. 1. Tworzymy nowy plik Rakefile o nazwie utils.rake w folde rze lib/tasks. 2. Do pliku utils.rake dodajemy następujące zadania Rake: namespace :utils do desc "Odnajduje niedługo wygasające subskrypcje ‘►i powiadamia użytkowników." task(:send expire soon emails > ¡environment) do # O dnalezienie użytkowników, do których m a zostać wysłany e-m ail
for user in User.members soon to expire puts "Wiadomość e-mail wysłana do użytkownika *►#{ u s e r .na me }" Us er No ti fi er.deliver expire soon ‘►notification (user) end end end
Warto zauważyć, że dzięki użyciu > en vi ro nm en t mamy dostęp do modeli. 3. By teraz wykonać skrypt, należy w wierszu poleceń wpisać następujący kod: rake utils:send expire soon emails # L u b by w ykonać za d an ie w trybie produkcyjnym
rake RAILS ENV production utils:send expire soon emails
4. Zadanie to może zostać dodane do skryptu cronjob: 0 0 * * * cd /var/www/apps/rails app/ && /u sr /local/bin/ e*rake \ RAILS ENV produc ti on ut il s: se nd expire e*soon emails
Dodatkowe informacje na temat własnych zadań Rake można zna leźć pod adresem http://www.miisenvy.com/2007/6/ll/ruby-on-raiisrake-tutorial. Railscast autorstwa Ryana Batesa poświęcony temu za gadnieniu znajduje się na stronie http://railscasts.com/episodes/66.
44
|
Rails. Leksykon kie szo n ko w y
Testowanie Rails Testowanie stało się bardzo istotnym elementem budowania wy sokiej jakości oprogramowania, które ma przetrwać próbę czasu. Dzięki dobremu przetestowaniu aplikacji możemy zminimalizo wać konieczność przepisywania kodu na nowo i uniknąć spędzania czasu na poszukiwaniu oraz usuwaniu błędów. Poniższa doku mentacja jest skrótem pochodzącym z podręcznika Ruby on Rails, rozdziałów 21 28 (http://manuals.mbyonrails.com/read/chapter/21). Uwaga Zgodnie z ankietą przeprowadzoną na stronie RailsEnvy.com około 61% program istów Rails używa programu RSpec (.h ttp://rspec.info), podczas gdy jedynie około 24% preferuje wbudowaną platformę Test Unit udostępnianą wraz z Rails. Zdecydowanie warto zapoznać się z RSpec, podobnie jak z innymi metodami testowania, których nie omówię w ni niejszej książce, takimi jak TDD (ang. test driven development: http://www.testdriven.com) czy dodatek Selenium IDE prze znaczony dla przeglądarki Firefox (http://selenium.openqa.org ).
W Rails poniższe trzy typy testów mają określone znaczenie, które może różnić się od tego, czego można by oczekiwać. Testy funkcjonalne Wykorzystywane są do testowania kontrolerów. Testy jednostkowe Wykorzystywane są do testowania modeli. Testy integracyjne Wykorzystywane są do testowania scenariuszy wyższego poziomu zakładających interakcję pomiędzy kontrolerami.
T e sto w a n ie Rails
|
45
Asercje Asercja (ang. assertiori) to pojedynczy wiersz kodu, który analizuje wyrażenie i testuje wynik w oparciu o oczekiwaną wartość. Przy kładowo możemy założyć, że hasło powinno się składać z przy najmniej sześciu znaków. Niepowodzenie tej asercji spowoduje niepowodzenie powiązanego z nią testu. Rails zawiera aktualnie sześć kategorii asercji.
Asercje DOM assert_dom_equal(expected, actual, message
"")
Sprawdza dwa łańcuchy HTML pod kątem równości (czyli powinny one być identyczne aż po zmianę kolejności atrybutów). assert_dom_not_equal(expected, actual, message Forma przecząca dla assert_dom_equivalent.
"")
Asercje modeli assert_valid(record)
Upewnia się, czy przekazany rekord jest poprawny zgodnie ze standardem ActiveRecord, i zwraca komunikaty o błędach, jeśli tak nie jest.
Asercje odpowiedzi assert_redirected_to(options
{}, message nil)
Upewnia się, że przekazane opcje przekierowania odpo wiadają opcjom przekierowania wywołanego w ostatniej akcji. Dopasowanie może być częściowe, zatem assert_ ^r edirected_to(:controller > "weblog") zostanie do pasowane do przekierowania redirect t o C :controller > "weblog",
46
|
:action
> "show").
Rails. Leksykon kie szo n ko w y
assert_response(type, message
nil)
Upewnia się, że odpowiedź jest jednym z następujących typów: :success
Kod statusu to 200. :redirect K od statu su m ieści się w zakresie od 300 do 399. :missing K od statu su to 404. :error K od statu su m ieści się w zakresie od 500 do 599
Można również przekazać kod statusu w jawny sposób, na przykład assert_response(501), lub w postaci jego sym bolicznego odpowiednika, assert_response( :not_imple "-»-mented). assert_template(expected
nil, message nil)
Upewnia się, że żądanie zostało wygenerowane za pomocą odpowiedniego pliku szablonu.
Upewnia się, że podane opcje mogą zostać użyte do wygene rowania podanej ścieżki. Jest odwrotnością assert reco agnizes. Parametr extras wykorzystywany jest do przeka zania żądaniu nazw oraz wartości dodatkowych parametrów żądania, które będą się znajdować w łańcuchu zapytania. Parametr message pozwala określić własny komunikat o błę dzie w przypadku niepowodzenia asercji. Parametr defaults nie jest używany.
Upewnia się, że routing dla podanej ścieżki został obsłużony w sposób poprawny i że opcje przetwarzania (podane w tablicy expected options) dopasowały ścieżkę. Upewnia się, że Rails rozpoznaje trasę podaną w expected options. By określić metodę żądania, należy w drugim argumencie (ścieżce) przekazać tablicę asocjacyjną. Przydaje się to dla tras wymagających określonych metod HTTP. Tablica ta powinna zawierać :path ze ścieżką żądania przychodzącego oraz :method zawierającą wymaganą metodę HTTP: # Upew nienie się, ż e użycie m etody PO ST d la /item s # w yw oła a k cję c r ea te na Item sC on troller
assert reco gn iz es ({:controller ^'create'}, {¡path > 'items',
> 'items', ¡action ¡method > ¡post})
>
Można również przekazać parametr extras z tablicą aso cjacyjną zawierającą parametry adresu URL, które normalnie znajdowałyby się w łańcuchu zapytania. Można to wyko rzystać do upewnienia się, że wartości z łańcucha zapytania w poprawny sposób trafią do tablicy asocjacyjnej params. By przetestować łańcuchy znaków zapytań, należy użyć argumentu extras. Bezpośrednie dodanie łańcucha zapytania do ścieżki nie zadziała. Przykład: # Upewnienie się, ż e ścieżka '/items/list/1 ?view print' zw raca p op raw n e op cje
Upewnia się, że ścieżka oraz opcje pasują do siebie obustronnie, czyli weryfikuje, czy ścieżka generuje opcje, a także czy opcje gene rują ścieżkę. Łączy zatem assert recognizes oraz assert_ ^ g e n e r a t e s w jeden etap. Tablica asocjacyjna extras pozwala na określenie opcji, które normalnie byłyby podane jako łańcuch zapytania do akcji. Pa rametr message pozwala na określenie własnego komunikatu o błędzie, który będzie wyświetlany w razie niepowodzenia.
Asercja wybierająca elementy i wykonująca jeden lub więk szą liczbę testów równości. Jeśli pierwszy argument jest elementem, wybiera wszystkie pasujące elementy od tego elementu (z nim włącznie) oraz wszystkie jego elementy potomne w kolejności zgodnej z głębokością. Jeśli żaden element nie zostanie określony, wywołanie assert_ ^ s e l e c t spowoduje wybranie z kodu HTML odpowiedzi. Wywołanie assert select wewnątrz bloku assert select spowoduje wykonanie asercji dla każdego elementu wybra nego przez asercję zewnętrzną. Przykład: assert select "ol>li" do elements e l e m e n t s .each do element assert select element, "li" end end
T e sto w a n ie Rails
|
49
Lub krócej: assert select "ol>li" do assert select "li" end
assert_select_email { }
Powoduje ekstrakcję ciała wiadomości e-mail i wykonuje na nim zagnieżdżone asercje. By asercja ta działała, konieczne jest załączenie dostarczania. Użycie: A c t i o n M a i l e r ::B a s e .perform deliveries
assert_select_encoded(element?)
true
{ |elements | ... }
Dokonuje ekstrakcji zawartości elementu, traktuje ją jak kod HTML i wykonuje na niej zagnieżdżone asercje. Zazwyczaj wywołuje się tę metodę wewnątrz innej asercji, tak by działała na wszystkich wybranych aktualnie elementach. Można również przekazać jej element bądź tablicę elementów. Zawartość każdego elementu jest odkodowywana i opakowywana w element główny encoded. Następnie wywoływany jest blok ze wszystkimi niezakodowanymi elementami. assert_select_rjs(*args) { |matches|
... }
Wybiera zawartość z odpowiedzi RJS. Zaw ężanie
Bez podania argumentów upewnia się, że jeden lub większa liczba argumentów zostanie uaktualniona lub wstawiona przez instrukcje RJS. Argument id należy wykorzystać do zawężenia asercji jedynie do instrukcji uaktualniających lub wstawiających element o poda nym identyfikatorze.
50
|
Rails. Leksykon kie szo n ko w y
Pierwszy argument należy wykorzystać do zawężenia asercji jedynie do instrukcji określonego typu. Możliwe wartości to :replace, :replace_html, :show, :hide, :toggle, :remove oraz :insert_html.
By zawęzić asercję jedynie do instrukcji wstawiających elementy na danej pozycji, należy użyć argumentu : insert, po którym następuje pozycja wstawienia. Możliwe wartości to :top, :bottom, : before oraz : after. Dzięki użyciu instrukcji : remove możliwe będzie przekazanie bloku, jednak zostanie on zignorowany, gdyż dla tej instrukcji nie przeka zano kodu HTML. W ykorzystyw anie bloków
Bez bloku assert select rj s upewnia się, czy odpowiedź zawiera jedną lub większą liczbę instrukcji RJS zastępujących lub uaktual niających zawartość. Z blokiem a s s e r t s e l e c t r j s wybiera wszystkie elementy wy
korzystane w instrukcjach i przekazuje je do bloku. Obsługiwane są zagnieżdżone asercje. Wywołanie assert select rjs bez argumentów i z wykorzysta niem zagnieżdżonych asercji umożliwia upewnienie się, że za wartość HTML jest zwracana przez jedną lub większą liczbę in strukcji RJS. Bezpośrednie użycie assert select pozwala wykonać tę samą asercję na zawartości, jednak bez rozróżnienia, czy za wartość ta zwracana jest w kodzie HTML, czy też JavaScripcie. css_selec t(*args)
Wybiera i zwraca wszystkie pasujące elementy. Po wywołaniu z pojedynczym argumentem wykorzystuje ten argument jako selektor dopasowujący wszystkie elementy bieżącej strony. Jeśli żadne dopasowanie nie zostanie od nalezione, zwraca pustą tablicę.
T e sto w a n ie Rails
|
51
Po wywołaniu z dwoma argumentami wykorzystuje pierw szy z nich jako element bazowy, a drugi jako selektor. Próbuje dopasować element bazowy oraz jego elementy potomne. Jeśli żadne dopasowanie nie zostanie odnalezione, zwraca pustą tablicę.
Asercje znaczników assert_no_tag(*opts) Identyczne z assert tag, jednak upewnia się, że dopasowany
znacznik nie istnieje (pełne omówienie składni znajduje się przy opisie assert_tag). assert_tag(*opts)
Upewnia się, że w ciele odpowiedzi znajduje się znacznik (węzeł, element) spełniający wszystkie podane warunki. Parametr warunków musi być tablicą asocjacyjną składającą się z dowolnej liczby poniższych kluczy (wszystkie są opcjonalne): :tag
Typ węzła musi odpowiadać podanej wartości. :attributes
Tablica asocjacyjna. Atrybuty węzła muszą odpowiadać wartościom podanym w tej tablicy. :parent
Tablica asocjacyjna. Węzeł nadrzędny węzła musi od powiadać wartościom podanym w tej tablicy. :child
Tablica asocjacyjna. Przynajmniej jeden bezpośredni węzeł potomny określonego węzła musi odpowiadać kryteriom opisanym w tej tablicy.
52
|
Rails. Leksykon kie szo n ko w y
:ancestor
Tablica asocjacyjna. Przynajmniej jeden węzeł nadrzędny określonego węzła musi odpowiadać kryteriom opisa nym w tej tablicy. :descendant
Tablica asocjacyjna. Przynajmniej jeden węzeł potomny określonego węzła musi odpowiadać kryteriom opisa nym w tej tablicy. :sibling
Tablica asocjacyjna. Przynajmniej jeden węzeł będący rodzeństwem określonego węzła musi odpowiadać kryteriom opisanym w tej tablicy. :after
Tablica asocjacyjna. Węzeł musi się znajdować po węźle rodzeństwa odpowiadającym kryteriom opisanym w tej tablicy. Przynajmniej jeden węzeł rodzeństwa musi zostać dopasowany. :before
Tablica asocjacyjna. Węzeł musi się znajdować przed dowolnym węzłem rodzeństwa odpowiadającym kryte riom opisanym w tej tablicy. Przynajmniej jeden węzeł rodzeństwa musi zostać dopasowany. :children
Tablica asocjacyjna służąca do zliczania węzłów po tomnych danego węzła. Przyjmuje następujące klucze: :count
Liczba lub zakres, który musi być równy liczbie pasujących węzłów potomnych (bądź musi tę liczbę zawierać). :less_than
Liczba pasujących węzłów potomnych musi być mniejsza od tej liczby.
T e sto w a n ie Rails
|
53
:greater_than
Liczba pasujących węzłów potomnych musi być większa od tej liczby. :only
Kolejna tablica asocjacyjna zawierająca klucze, które wykorzystuje się do dopasowania węzłów potomnych. Zliczone zostaną jedynie pasujące węzły potomne. :content
Zawartość tekstowa węzła musi pasować do podanej wartości. Nie zostaną dopasowane znaczniki HTML znajdujące się w ciele znacznika, a jedynie tekst. Warunki dopasowywane są za pomocą następujących al gorytmów: • Jeśli warunek jest łańcuchem znaków, musi to być podłańcuch podanej wartości. • Jeśli warunek jest wyrażeniem regularnym, musi dopa sować wartość. • Jeśli warunek jest liczbą, wartość musi pasować do nu mber.to_s.
• Jeśli warunek to tru e, wartość nie może być nil. • Jeśli warunek to false, wartość musi być nil.
Testy funkcjonalne W Rails testy funkcjonalne wykorzystuje się do przećwiczenia jednej opcji czy funkcji w kontrolerze. Testy funkcjonalne oraz integracyjne sprawdzają odpowiedzi na polecenia zwane żąda niami HTTP.
54
|
Rails. Leksykon kie szo n ko w y
Pytania, na jakie odpowiedzi można uzyskać za pomocą testów funkcjonalnych, mogą być następujące: • Czy żądanie zakończyło się powodzeniem? • Czy zostaliśmy przekierowani do właściwej strony? • Czy udało nam się wykonać uwierzytelnienie? • Czy właściwy obiekt został przechowany w szablonie od powiedzi? Tak samo jak istnieje stosunek jeden do jednego pomiędzy testami jednostkowymi a modelami, podobnie jest w przypadku testów funkcjonalnych oraz kontrolerów. Dla kontrolera o nazwie Home ^ C o n t r o l l e r tworzymy przypadek testowy o nazwie HomeCon "-»-trollerTest.
Poniżej znajduje się przykład testu funkcjonalnego: require F i l e .dirname(
FILE
) +
'/../test helper
# P o b ran ie kon trolera UsersController, pon iew aż będziem y g o testow ać
require
'users controller'
# Z głaszanie błędów w ykraczających p o z a dom yśln ąprezen tację internetow ą
def test index get :index assert response ¡success end end
T e sto w a n ie Rails
|
55
W metodzie setup tworzymy trzy obiekty: • jeden z kontrolerów, który ma być przetestowany (@con "-»•tr o lle r ); • TestRequest z symulacją żądania (^request); • TestResponse udostępniający informacje o żądaniu testo wym ((^response). W dziewięćdziesięciu dziewięciu (jeśli nie stu) procentach przy padków testy funkcjonalne będą zawierały te trzy obiekty. W metodzie t e s t i n d e x wykorzystujemy obiekty utworzone w metodzie setup oraz protokół get do otrzymania odpowiedzi z akcji : index. Następnie upewniamy się, że typem odpowiedzi był : success. Wszystkie typy żądania to metody, jakich można użyć. Najczęściej okazuje się jednak, że to z dwóch pierwszych będziemy korzystać o wiele częściej niż z pozostałych. W Rails obsługiwanych jest pięć typów żądań: • get/ • post, • put/
• head, • delete.
Testy funkcjonalne oparte na kontrolerach Poniżej znajdują się dwa przypadki testowe wykorzystywane do sprawdzania uwierzytelnienia. def test failing authenticate process 'authenticate1, { "user name" ^►"password" > "" }
56
|
Rails. Leksykon kie szo n ko w y
> "missing password",
assert redirect url "h t t p :/ / lo ca lh os t:30 00 /login/" end def test succesful authentication process 'authenticate1, { "user name" > "cavneb", ‘►"password" > "mysecret" } assert redirect url "h t t p :/ / lo ca lh os t:3000/dashboard/" end
Metoda process wyzwala kontroler z podaną akcją (pierwszy parametr), a także z opcjonalnymi parametrami żądania (to jest zmiennymi form post). Następnie, po wygenerowaniu odpowiedzi, można ją zbadać i przekonać się, czy wszystko poszło zgodnie z założeniami.
Testy funkcjonalne oparte na widokach Dobrym pomysłem jest wymaganie, by widoki tworzyły popraw ny składniowo oraz strukturalnie kod XHTML. Poniższy kod pozwala zanalizować wyniki za pomocą analizatora składnio wego XML. def test show conversation response
ForumController.process test(@request)
# Analiza składniowa wynikowego kodu HTML na obiekt REXML:/Document # Je śli dane wyjściowe nie sąpopraw nym składniowo kodem XML, zwracany je s t wyjątek
output
D o c u m e n t .new(r e s p o n s e .b o d y )
# Tutaj można wykorzystać A PI dla REXML, w tym XPath, do pobrania # części danych z kodu XML
end
Poniżej znajduje się przykład sytuacji, w której REXML: : XPath można wykorzystać do przetestowania danych wyjściowych z szablonu. require
xml nil assert nothing thrown { xml ^ ( r e s p o n s e .body) }
R E X M L ::Do c u m e n t .new
# P o b ra n ie wszystkich hiperłączy zn ajdujących s ię gdzieś g łę b o k o w odpow iedzi
title hrefs R E X M L ::X P a t h .ma t c h ( x m l , 1/html/body/table/ ^t r[ 2] /t d/ ta bl e/ tr [l] /t d/ a1) # Sprawdzenie, ż e istnieją trzy h iperłącza...
assert equal 3, title hrefs.size #... i ż e kieru ją użytkownika tam, g d zie pow inny h r e f urls t i t l e h r e f s . m a p {|element| e l e m e n t .a t t r i b u t e ( 1h r e f 1).v a l u e } . sort
assert equal [ 1/conversation/show?id 1', /message/new?conv id 1'], href urls
'/forum/?id 1',
end
Więcej informacji na temat testów funkcjonalnych znajduje się na stronie http://wiki.rubyonrails.org/mils/pages/HowtoFunctionalTest.
Fikstury Fikstury (ang. fixture) pozwalają wypełnić testową bazę danych za pomocą zdefiniowanych wcześniej danych przed wykonaniem te stów. Są niezależne od bazy danych i przyjmują jeden z dwóch formatów YAML bądź CSV (wartości rozdzielone przecinkami). Fikstury znajdują się w katalogu test/fixtures. Kiedy wykonujemy sc ri pt /g en er at e model w celu utworzenia nowego modelu, fikstury są tworzone automatycznie i umieszczane w tym katalogu.
YAML YAML to przyjazny dla człowieka standard serializacji przezna czony dla wszystkich języków programowania.
58
|
Rails. Leksykon kie szo n ko w y
# Przykładow y p lik YAML
eric : id: 1 name: Eric Berry birthday: 1977-04-15 profession: Software Engineer aubree: id: 2 name: Aubree Berry birthday: 1985-11-30 profession: Medical Assistant
Każda fikstura otrzymuje nazwę, po której następuje wcięta lista par klucz wartość rozdzielonych dwukropkami. Rekordy oddzie lone są od siebie pustym odstępem. Komentarze można umieszczać w pierwszej kolumnie za pomocą znaku #.
Wartości rozdzielone przecinkami Fikstury można również opisywać za pomocą dobrze znanego formatu pliku z wartościami rozdzielonymi przecinkami (CSV). Pliki te, podobnie jak fikstury w formacie YAML, umieszczane są w katalogu test/fixtures, jednak kończą się rozszerzeniem ,csv (na przykład tworząc plik test users.csd). Fikstura w formacie CSV wygląda następująco: id, name, birthday, profession 1, "Eric Berry", 1977-04-15, "Software Engineer" 2, "Aubree Berry", 1985-11-30, "Medical Assistant"
Pierwszy wiersz to nagłówek; składa się on z rozdzielonej prze cinkami listy pól. Pozostała część pliku zawiera dane rekordów. Kilka uwag na temat tego formatu: • Spacje na początku i końcu komórek są usuwane. • Jeśli elementem danych jest przecinek, taka komórka musi się znaleźć w cudzysłowie.
T e sto w a n ie Rails
|
59
• Jeśli elementem danych jest cudzysłów, musi zostać poprze dzony drugim cudzysłowem. • Nie należy używać pustych wierszy. • Wartość NULL można uzyskać, umieszczając sam przecinek. W przeciwieństwie do formatu YAML, w którym każda fikstura otrzymuje nazwę, nazwy fikstur CSV generowane są automatycznie. Są one zgodne z wzorcem model nazwa lic z n ik . W poprzednim przykładzie otrzymalibyśmy: test-users-l test-users-2
Format CSV świetnie nadaje się do użycia, jeśli mamy istniejące dane w arkuszu kalkulacyjnym bądź bazie danych i jesteśmy w stanie je zapisać (lub wyeksportować) jako CSV.
ERb w YAML oraz CSV ERb pozwala osadzać kod Ruby wewnątrz szablonów. Formaty fikstur YAML oraz CSV są wstępnie przetwarzane za pomocą ERb, co pozwala wykorzystać język Ruby do pomocy w wygenerowa niu pewnych przykładowych danych. <% average weight
60
100 -%>
a v er ag e: id: 1 weight: <%
average weight %>
heavy: id: 2 weight: <%
average weight * 2 %>
light: id: 3 weight: <%
average weight / 2 %>
|
Rails. Leksykon kie szo n ko w y
Atrapy Atrapy (ang. mock) to klasy ładowane w środowisku testowym na końcu i mające w zamierzeniach nadpisywać metody klas, które nie powinny być wykonywane. Przykładowo jeśli częścią testu jest interakcja z zewnętrzną usługą sieciową, na przykład obsługującą płatności, przekazywanie do niej danych w trakcie testowania może nie być najlepszym pomysłem. Poniższy kod może przedstawiać klasę oraz metodę przesyłającą dane do bramki obsługującej płatności. class PaymentCateway def process order # K o d skła d ający zam ów ien ie do program u p rzetw arzająceg o pła tn o ści
By utworzyć atrapę, wystarczy napisać klasę znajdującą się w folderze test/mocks/[środowisko] . require
1path/to/payment g a t e w a y 1
class PaymentCateway def process order # M etoda n adpisu jepraw dziw ąm etodęP ay m en tG atew ay process order true end end
Testy jednostkowe dla modeli W Rails testy jednostkowe przeznaczone są do testowania modeli. Załóżmy, że testujemy model Product, zawierający poniższe walidacje: # app/m odełs/Product.rb
class < A c t i v e R e c o r d ::Base validates presence of validates numericality of validates uniqueness of validate
:name, :price, ¡quantity ¡quantity ¡name ¡price must be greater than zero
T e sto w a n ie Rails
|
61
protected def price must be greater than zero e r r o r s .a d d ( :p r i c e , 'powinna mieć wartość co ^najmniej O . O l 1) if price.nil? || price < 0.01 end end
Przyglądając się walidatorom, wiemy już, co mamy sprawdzić w teście jednostkowym. Zacznijmy od utworzenia fikstur, z któ rych będziemy korzystać. # test/fixtures/products.yml
soccer ball: name: Piłka do piłki nożnej price: 17.50 quantity: 25
Skoro mamy już fikstury, utwórzmy testy jednostkowe: # test/unit/pr o d u c tje s t.r b
require F i l e .di rn am e(
FILE
) +
'/../test helper'
class ProductTest < Ac ti ve S u p p o r t : :TestCase # Z aładow an ie fikstu r utworzonych na c e le testów
fixtures
¡products
def test invalid with empty attributes product Product.new assert !p r o d u c t .valid? end def test name error with empty attributes product Product.new p r o d u c t .valid? # Wywołuje w alid ację assert !p r o d u c t .errors.invalid?(:name) end def test price error with empty attributes product Product.new p r o d u c t .valid? # Wywołuje w alid ację assert !p r o d u c t .erro rs .i nv al id ?(:price) end def test quantity error with empty attributes product Product.new
62
|
Rails. Leksykon kie szo n ko w y
product.valid? # Wywołuje walidację assert !p r o d u c t .e r r o r s .inva li d?( ¡quantity) end def test invalid with duplicate name product Product.n e w ( :name > products(:soccer ball) . ^name, ¡price > 20.00, ¡quantity > 30) p r o d u c t .save assert equal "ta nazwa jest już zajęta", product.e r r o r s . ^ o n (:n a m e ) end def test invalid with price less than or equal to zero product P r od uc t.n e w ( :name > 'Piłka do tenisa', ^: pr ic e > 0.00, ¡quantity > 3) p r o d u c t .save assert equal "powinna mieć wartość co najmniej 0.01", ^►product.e r r o r s .o n ( ¡price) end end
Po utworzeniu testu istnieje kilka sposobów wykonania go. Można albo zrobić to w sposób bezpośredni, za pomocą Ruby: ruby test/unit/product test.rb
albo wykonać wszystkie testy razem za pomocą polecenia rake test. rake test
Po wykonaniu testu powinniśmy zobaczyć coś w stylu: Loaded suite test/unit/product test Started Finished in 0.044915 seconds. 3 tests, 8 assertions, 0 failures, 0 errors
Wskazówka Zazwyczaj za dobrą praktykę uznawane jest posiadanie jednej asercji w każdym teście. W ten sposób wszystkie testy zo staną wykonane, a my zaoszczędzimy nieco czasu na etapie debugowania.
T e sto w a n ie Rails
|
63
Konsola Rails Konsola Rails jest narzędziem, z którego korzystam niemalże za każdym razem, gdy zabieram się do programowania to se kretna broń programistów Rails. Konsolą Rails jest interaktywna powłoka Ruby (irb), w której załadowana jest aplikacja Rails. Dzięki niej można: debugować kod, zobaczyć wyniki dowolnego fragmentu kodu, wykonać CRUD na modelach za pomocą ActiveRecord. By uruchomić konsolę z folderu głównego aplikacji Rails, należy wpisać: ./script/console # M ożna rów nież za ład ow ać ok reślon e środow isko ./script console p r o d u c t i o n
Powinniśmy zobaczyć coś w stylu: Loading development environment (Rails 2.1.0)
>>
Znaki » to zachęta dla poleceń Ruby. By wyjść z konsoli, należy wpisać exit lub użyć skrótu klawiatu rowego Ctrl+Z.
Sztuczki zw iązane z konsolą Istnieje kilka mniej znanych opcji konsoli Rails, które każdemu mogą się przydać.
64
|
Rails. Leksykon kie szo n ko w y
Dostęp do ostatniej zwracanej wartości za pomocą _ Kiedy korzysta się z konsoli, czasami można zapomnieć przypisać zwracaną wartość do zmiennej, by móc z niej później korzystać. Konsola udostępnia magiczną zmienną _, do której przypisywana jest ostatnia wartość zwracana przez konsolę. Przykład: »
Uruchomienie konsoli w trybie sandbox Powiedzmy, że musimy przetestować fragment kodu w prawdzi wym środowisku, ale nie chcemy wprowadzać żadnych zmian do bazy danych. Można to zrobić dzięki użyciu w konsoli opcji sandbox.
Przykład: ./script/console production --sandbox Loading production environment in sandbox (Rails 2.1.0) Any modifications you make will be rolled back on exit >> movie M o v i e .fin d (: f i r s t ) > # >> movie.title "Eleventh Hour, The" > "Eleventh Hour, The" >> movie.save > true » exit
Ko n sola Rails
|
65
# Teraz przeład o w an ie kon soli
./script/console production Loading production environment (Rails 2.1.0) » Movie .-fin d ( :first ) > #
Zwracanie obiektów do YAML za pomocą polecenia y Kiedy przegląda się obiekty w konsoli Rails, mogą one się okazać trudne do odczytania. Polecenie y sprawi, że obiekt łatwiej będzie odczytać. Przykład: >> movie Movie .“fin d ( :first ) > # >> y movie — !ru by / o b j e c t :Movie attributes : updated at: 2008-04-10 00:24:06 title: 11th Hour, The id: "1" created at: 2008-04-10 00:24:06 attributes cache: {} > nil
>>
Formatowanie za pomocą metod pomocniczych z użyciem helper By uzyskać dostęp do metod pomocniczych z konsoli aplikacji Rails, można użyć obiektu helper. Przykłady: >> h e l p e r .pluralize(3, > "3 bottles"
'bottle')
>> helper.text areaCifoo, :bar) > ""
66
I
Rails. Leksykon kie szo n ko w y
Dostęp do kontrolerów za pomocą obiektu app W konsoli można uzyskać dostęp do kontrolera projektu za pomocą obiektu app. Dzięki temu możliwe jest wykonywanie żądań HTTP do kontrolera. Przykłady: >> app.class > A c ti on Co nt ro ll er: ¡Integration:¡Session # Otrzymanie odpow iedzi na żą d an ie skierow an e d o '/movies' » a p p .get 1/movies 1 > 200 # U staw ienie zaw artości zm iennej 'flash' b ęd ą ce j ta b lic ą asocjacyjn ą » app.flash
> {} # P rzejrzen ie c o o k ies dla tej ap likacji R ails » app.cookies
^dOeS"} Więcej wskazówek dotyczących wykorzystywania konsoli Rails można znaleźć na blogu Amy Hoy pod adresem http://slash7.com/ articles/2006/12/21/secrets-of-the-rails-console-ninjas lub w podcaście Ryana Batesa dostępnym na stronie http://railscasts.com/ą>isodes/48.
ActiveRecord oraz modele ActiveRecord łączy obiekty biznesowe oraz tabele bazy danych w celu utworzenia ciągłego modelu domenowego, w którym logika oraz dane prezentowane są w jednym opakowaniu. Więcej informacji na temat ActiveRecord można znaleźć pod adresem http://ar.rubyonrails.com.
A ctiveR eco rd o ra z m odele
|
67
Migracje Migracje można sobie wyobrazić jako repozytorium wersji prze znaczone dla schematu bazy danych. Dzięki migracjom można tworzyć wersje schematu bazy danych i przechodzić do kolejnej wersji lub wracać do poprzedniej, kiedy tylko chcemy. Jest to bardzo wygodne dla programistów, którzy chcą tylko dodać niewielkie zmiany do tabeli bez konieczności przebudowywania całej bazy danych. Rails udostępnia generator służący do tworzenia migracji: ./script generate migration N a z w a M ig r a c ji [opcje]
W powyższym przykładzie generator tworzy klasę migracji w katalogu db/migrate z numerem wersji dołączonym jako przedro stek do nazwy. W Rails 2.1 wprowadzono migracje oparte na UTC, które korzystają z unikalnego przedrostka, który ma mniejsze szanse wejść w konflikt z inną migracją, którą ktoś inny mógł dodać do repozytorium w tym samym czasie. Przykład: class CreateMovies < A c t i v e R e c o r d ::Migration def s e l f .up create table :movies do |t| t.string :title t.integer :genre id t.string ¡rating, ¡limit > 5 t.string ¡short description t.text :long description t.boolean :is new release, ¡default t.timestamps end # D o d an ie klucza ob c eg o
add index ¡movies,
¡genre id
end def s e l f .down drop table end
¡movies
end
68
|
Rails. Leksykon kie szo n ko w y
> false
W przykładzie tym utworzyliśmy tabelę o nazwie movies z kolum nami title, genre_id, rating, short_description, long_descrip ^tio n oraz is new release. Wygenerowano również standardowe wartości daty i czasu o nazwach created at oraz updated at. Utworzone zostało również indeksowanie po kluczu obcym.
Odwzorowywanie typów kolumn W tabeli 1.2 zaprezentowano listę wygenerowanych typów kolumn w oparciu o wykorzystywaną bazę danych. Tabela 1.2. Odwzorowania typów kolumn Typ m igracji
M ySQ L
Po stgreSQ L
SQ Lite
O racle
:string
Varchar (255)
character varying ( 255 )
Varchar (255)
varchar2 (255)
:text
text
text
text
clob
:integer
int(ll)
integer
integer
number(38)
:"float
"float
"float
"float
number
:decimal
decimal
decimal
decimal
decimal
:datetime
datetime
timestamp
datetime
date
:timestamp
datetime
timestamp
datetime
date
:time
time
time
datetime
date
:date
date
date
date
date
:binary
blob
bytea
blob
blob
:boolean
tinyint(l)
boolean
boolean
number(l)
Opcje kolumn Typy kolumn zezwalają również na użycie opcji. Żeby na przykład utworzyć kolumnę z łańcuchem znaków, która w tabeli może mieć maksymalnie 55 znaków, można skorzystać z poniższego kodu: t.string
:address,
:limit
> 55
Poniżej opisano dostępne opcje wraz z typami kolumn, z jakimi mogą one być użyte.
A ctiveR eco rd o ra z m odele
|
69
:default
> wartość
Domyślnie ustawia podaną wartość. Opcję tę można wyko rzystać ze wszystkimi typami kolumn. :limit
> rozmiar
Dodaje parametr wielkości do kolumn tekstowych, binarnych, z łańcuchami znaków lub liczbami całkowitymi. :null
> true
Sprawia, że kolumna jest wymagana na poziomie bazy da nych, ustawiając na niej ograniczenie not nuli. :precision
> liczba
Całkowita liczba cyfr w liczbie. Do wykorzystania jedynie z typami : decimal. :scalę
> liczba
Całkowita liczba cyfr znajdujących się po prawej stronie od znaku dziesiętnego. Do wykorzystania jedynie z typami :decimal.
Uruchomienie migracji By uruchomić skrypt migracji, należy wpisać: rake db:migrate
Spowoduje to wykonanie wszystkich nowych skryptów migracji i uaktualnienie bazy danych. By skrypt migracji wykonać na określonym środowisku, należy użyć: rake db:migrate RAILS ENV [ ś r o d o w i s k o ]
Pow iązania Powiązania (ang. associations) to metoda klasy wykorzystywana do ustalania związków pomiędzy obiektami za pomocą kluczy obcych. Dzięki powiązaniom związki, takie jak „Użytkownik ma wiele
70
|
Rails. Leksykon kie szo n ko w y
komentarzy" czy „Komentarz przynależy do działu Film y", są ustanawiane automatycznie. Każde makro dodaje pewną liczbę metod do klasy. Metody są specjalizowane zgodnie z kolekcją czy symbolem powiązania oraz tablicą asocjacyjną opcji. Działa to w przybliżeniu tak samo jak własne metody attr języka Ru by. Więcej informacji na temat powiązań można znaleźć pod adresem htfp://ąńMibi/onrails.org/classes/ActiveRecord/Associatioiis/Class Methods.html. Istnieją następujące standardowe powiązania.
Jeden do jednego Należy użyć has one w bazie oraz belongs to w powiązanym modelu: class Picture < Ac t i v e R e c o r d ::Base has one :thumbnail end class Thumbnail < A c t i v e R e c o r d ::Base belongs to :picture end
Powiązanie to przedstawione zostało na rysunku 1.1. pictures
id
title
[ ¡ S lip
1*— i |
■ —
thumbnails id picturejd title
1
Rysunek 1.1. Powiązanie jeden do jednego
Jeden do wielu Należy użyć hasmany w bazie oraz b e l o n g s t o w powiązanym modelu: class Category < A c t i v e R e c o r d ::Base has many :products
A ctiv e R e c o rd o ra z m o d e le
|
71
end class Product < A c t i v e R e c o r d ::Base belongs to :category end
Powiązanie to przedstawione zostało na rysunku 1.2.
Rysunek 1.2. Powiązanie jeden do wielu
Wiele do wielu Istnieją dwa sposoby budowania związków wiele do wielu. Pierw sza i preferowana metoda wykorzystuje powiązanie has many z opcją : through oraz modelem łączenia, dlatego istnieją dwa etapy powiązania: class UserRole < A c t i v e R e c o r d ::Base belongs to :user belongs to :role end class User < A c t i v e R e c o r d ::Base has many :user roles has many :roles, ¡through > ¡user roles end class Role < A c t i v e R e c o r d ::Base has many ¡user roles has many ¡users, ¡through > ¡user roles end
72
|
Rails. Leksykon k ie s z o n k o w y
Druga metoda wykorzystuje powiązanie has_and_belongs_to_ ^►many w obu modelach. Wymaga to połączonej tabeli niemającej odpowiadającego jej modelu lub klucza pierwotnego: class User < A c t i v e R e c o r d ::Base has and belongs to many :roles end class Role < A c t i v e R e c o r d ::Base has and belongs to many :users end
Powiązanie to przedstawione zostało na rysunku 1.3.
Rysunek 1.3. Powiązanie wiele do wielu
Powiązania polimorficzne Powiązania polimorficzne to modele, które można wykorzystać jako jeden lub większą liczbę klas modeli. Do utworzenia powiązania polimorficznego konieczne są trzy kroki: 5 .Zadeklarowanie interfejsu. Klasa wykorzystywana jako powiązany model tworzy inter fejs, z którym mogą wiązać się inne modele. Przykładowo klasa Address udostępnia interfejs o nazwie addressable: class Address < A c t i v e R e c o r d ::Base belongs to ¡addressable, ¡polymorphic end
> true
A ctiv e R e c o rd o ra z m o d e le
|
73
Powiązanie belongs to musi mieć nazwę oraz atrybut :polymorphic.
6. Utworzenie powiązania z interfejsem. Każda klasa, która będzie powiązana z klasą współdzieloną, musi zadeklarować to powiązanie poprzez wcześniej za deklarowany interfejs. Przykładowo klasa User wiąże się z klasą Address za po średnictwem interfejsu addressable: c l a s s U s e r < A c t i v e R e c o r d : : Base h as one : a d d r e s s , : a s > : addressable end
Powiązanie (w tym przypadku hasone) ma nazwę i odnosi się do interfejsu za pośrednictwem atrybutu :as. Możliwe powiązania to has_one oraz has_many. 7 .Użycie powiązania w normalny sposób. bob U s e r . f i n d ( 7) bob. a d d r e s s
# #
> # > # < A ddress:0x238eaac @ attribu tes {...}>
frank User.find(3) frank, cr ea te a d d r e s s ( . . . )
Gdybyśmy przeszli do tego samego adresu URL, ale zamiast roz szerzenia Mml użyli .xml, otrzymalibyśmy całkowicie odmienną odpowiedź widoczną w przykładzie 1.2. Przykład 1.2. Plik people.xml «people type "array"> Dave Andersonldavid.andersonOoreilly,com
Z rozszerzeniem .json otrzymalibyśmy to, co widać w kodzie przykładu 1.3. Przykład 1.3. Plik people.json [{"person": {"id": 1, "first name": "Dave", "last name": e*"Anderson", "email": "[email protected]"}}]
Wykorzystywanie własnych formatów w połączeniu z respond to Dzięki możliwościom Rails możemy nawet tworzyć własne for maty. Załóżmy, że chcemy napisać aplikację o osobnym układzie dokumentu oraz widoku przeznaczonym dla użytkowników tele fonów iPhone. 1 .Zaczynamy od zarejestrowania typu MIME o nazwie iphone w pliku config/initializers/mime types: M i m e ::T y p e .register alias "text/html",
108
|
Rails. Leksykon kie szo n ko w y
:iphone
2. Teraz możemy dodać widok przeznaczony specjalnie dla użytkowników tego telefonu (app/views/people/index.iphone.erb):
<% "#{person.first name} # { p e r s o n .last name}" ^%>
<% end -%>
3. Możemy również utworzyć układ dokumentu zgodny z prze wodnikiem stylu telefonu iPhone {app/views/layouts/iphone. html.erb): < IDOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 St nc t / / E N "
h t t p :/ / w w w .w 3 .or g/ TR/xhtmll/DTD/xhtmll-strict.d t d "> <1ink rel "apple-touch-icon" href "/images/myapp.png"> Moja aplikacja <1ink rel "stylesheet" href "/stylesheets/EdgeToEdge.css" /> Moja aplikacja <%
# W ygenerow anie odpow iedzi z a p o m o c ą m etody to j s o n
f o r m a t .iphone # W ygenerow anie pliku *.iphon e.erb
end end
5. Po przejściu do pliku http:/Aocalhost:3000/people.iphone powin niśmy już zobaczyć nowy format: < IDOCTYPE html PUBLIC " -//W3C//DTD XHTML 1.0 S t n c t / / E N " h t t p :/ / w w w .w 3 .or g/ TR/xhtmll/DTD/xhtmll-strict.d t d "> < 1 ink rel "apple-touch-icon" href "/images/myapp .png"> Moja aplikacja < 1 ink rel "stylesheet" href "/stylesheets/EdgeToEdge.css" /> Moja aplikacja
Dave Anderson
Szablony Builder Szablony Builder są alternatywą dla ERb. Są szczególnie przydatne przy generowaniu zawartości XML. Obiekt Builder: :XmlMarkup o nazwie xml staje się automatycznie dostępny dla szablonów z rozszerzeniem .builder.
110
|
Rails. Leksykon kie szo n ko w y
Poniżej znajduje się kilka prostych przykładów: x m l .d i v ( "c o ntents") #
>
contents
xml.h3 { x m l .strong("h3 & strong") #
x m l .a ( "Partner Fusion", #
}
> < h3> < stron g> hS & am p; strong< /stron g> < /h3>
"href" > " h t t p :// pa rtnerfusion.co m " )
> < a h r e f "http://partnerfusion.com ">P artner F u sion < /a>
Dowolna metoda z blokiem zostanie potraktowana jak znacznik kodu XML z zagnieżdżonym kodem w bloku. Na przykład po niższy kod: xml.div { x m l .hl(@person.name) x m l .p( @ p e r s o n .b i o )
} zwróciłby coś w stylu:
Ryan Williams
CEO of Partner Fusion.
Gdybym chciał utworzyć prosty kanał XML dla akcji generującej listę filmów, mógłbym dodać do akcji responder format: # apps/controllers/m ovies_con troller. rb
Dokumentacja szablonów Builder dostępna jest pod adresem http://builder.rubyforge.org. Szczegółowy przykład tworzenia pliku XML za pomocą języka Ruby oraz szablonu Builder można znaleźć w artykule Michaela Fitzgeralda znajdującym się pod adresem http://www.xml.com/ pub/a/2006/01/04/creating-xml-with-ruby-and-builder.html.
JavaScriptGenerator Szablony JavaScriptGenerator kończą się rozszerzeniem .rjs. W prze ciwieństwie do konwencjonalnych szablonów, które używane są do generowania wyników akcji, szablony te generują instrukcje dotyczące tego, jak należy zmodyfikować wyświetloną już stronę. Ułatwia to zmianę kilku elementów na stronie w jednej deklara tywnej odpowiedzi w technologii Ajax. Akcje z tych szablonów wywoływane są w tle za pomocą Ajaksa i uaktualniają stronę, z której pochodziło żądanie. Instancja strony nazwanej zgodnie z obiektem JavaScriptGenerator automatycznie udostępniana jest szablonowi, który początkowo opakowany jest w blok ActionView: :Helpers: : Prototype Helper update_page. Kiedy akcja .rjs zostanie wywołana z link to remote, wygenero wany kod w JavaScripcie jest automatycznie analizowany. Przykład: link to remote :url
> {:action
> 'delete'}
Wygenerowany w rezultacie plik delete.rjs może wyglądać na stępująco: page.replace html 'sidebar', :partial > 'sidebar p a g e .remove "pe rs on -# {@ pe rs on.i d } " page.visual effect :highlight, user-list
112
|
Rails. Leksykon kie szo n ko w y
Powoduje on odświeżenie paska bocznego, usuwa element person i podświetla listę użytkowników.
Wykorzystywanie szablonów podrzędnych Użycie szablonów podrzędnych pozwala uniknąć żmudnego po wtarzania i ująć struktury wyświetlane na większej liczbie stron we współdzielonych szablonach. Klasyczny przykład takiego rozwią zania to nagłówek oraz stopka (choć sposób wykorzystujący pakiet ActionPack korzystałby tutaj z układów dokumentów): <% render "shared/header" %> Coś bardzo specyficznego i wyjątkowego <% render "shared/footer" %>
Jak widać, wykorzystaliśmy metodę render w połączeniu z osa dzeniem z danymi wyjściowymi. Wywołanie render zwróci po prostu łańcuch znaków zawierający wygenerowany rezultat. Osa dzenie tego typu spowoduje zapisanie tego wyniku do aktualnego szablonu. Nie trzeba się jednak ograniczać do wstawiania danych statycz nych. Szablony mogą współdzielić między sobą zmienne dzięki korzystaniu ze zmiennych instancji definiowanych za pomocą zwykłych znaczników osadzających, jak poniżej. <% Ppage title "Serdeczne powitanie" %> <% render "shared/header" %>
Teraz nagłówek może pobrać zmienną @page_title i wykorzystać ją do zwrócenia znacznika t i t l e . <%
Ppage title %>
Jeśli jednak potrzebna nam jest większa doza kontroli nad wsta wianą zawartością, lepszym rozwiązaniem mogą być szablony częściowe.
W idoki
| 113
Szablony częściowe Szablony częściowe (ang. partials) to niewielkie zbiory kodu, które można dołączyć do dowolnej części widoku, a nawet wygenerować z kontrolera. Zazwyczaj przyjmują jako parametr przynajmniej jeden obiekt, jednak można je dostosować do własnych potrzeb, tak by przyjmowały dowolną ich liczbę. Szablony częściowe nazywane są z wykorzystaniem przedrostka _ w celu rozdzielenia ich od zwykłych szablonów, które można wygenerować osobno. W szablonie account dla kontrolera Advertiser możemy na przykład mieć kod: <%
render :partial
> "account" %>
Kod ten powoduje wygenerowanie pliku advertiser/ account Mml.erb i przekazanie zmiennej instancji ^account jako zmiennej lokalnej account do szablonu w celu wyświetlenia. W kolejnym szablonie dla kontrolera Advertiser o nazwie buy mo glibyśmy mieć kod: <% render :partial e*@buyer } %>
> "account",
<% for ad in ^advertisements %> <% render :partial > "ad", <% end %>
:locals
:locals
> { :account
> { :ad
>
> ad } %>
Kod ten najpierw wygenerowałby plik advertiser/ account Mml.erb ze zmienną @buyer przekazaną jako zmienna lokalna account, a następnie wygenerowałby plik advertiser/ ad Mml.erb i przekazał zmienną lokalną ad do szablonu w celu wyświetlenia jej.
Wygenerowanie zbioru szablonów częściowych Przykład użycia szablonów częściowych opisuje znany wzorzec, w którym szablon musi wykonać iterację po tablicy i wygenerować szablon podrzędny dla każdego z elementów. Wzorzec ten został
114
|
Rails. Leksykon kie szo n ko w y
zaimplementowany jako pojedyncza metoda przyjmująca tablicę i generująca szablon częściowy o tej samej nazwie co element w nim zawarty. Poprzedni trzywierszowy przykład można by zatem za stąpić pojedynczym wierszem: <%
render :partial
> "ad",
¡collection
> ^advertisements %>
Spowodowałoby to wygenerowanie pliku advertiser/ ad.html.erb i przekazanie zmiennej lokalnej ad do szablonu w celu wyświetle nia. Licznik iteracji automatycznie zostanie udostępniony szablonowi z nazwą w formie nazwa szablonu częściowego counter. W przypadku poprzedniego przykładu szablon otrzyma licznik ad counter. Uwaga Ze względu na wątpliwośd związane ze zgodnością ze starszymi wersjami kolekq'a nie może składać się z tablic asoq'acyjnych. Zazwyczaj trzyma się tam jedynie obiekty domenowe, takie jak ActiveRecords.
Powyższy kod wygeneruje szablon częściowy advertisement,/ ad. htmlerb bez względu na to, z którego kontrolera jest wywoływany.
Generowanie szablonów częściowych z układami dokumentów Do szablonów częściowych można zastosować ich własne układy dokumentu. Układy te różnią się od tych stosowanych globalnie dla całej akcji, jednak działają w podobny sposób. Wyobraźmy so bie listę z dwoma typami użytkowników:
W idoki
| 115
<%# app/views/users/index.html.erb %> Oto administrator: <% render ¡partial > "user", ¡layout > "administrator", ^¡lo ca ls > { :user > administrator } %> A oto redaktor: <% render ¡partial > "user", :user > editor } %>
¡layout
> "editor",
¡locals
>
<%# app/views/users/ u s e r .h t m l .erb %> Nazwisko: <% user.name %> <%# app/views/users/ admi ni st ra to r.h t m l .erb %>
Budżet: $<% user.budget %> <% yield %>
<%# app/views/users/ e d i t o r .h t m l .erb %>
Termin: $<% u s e r .deadline %> <% yield %>
Powyższy kod da następujący wynik: Oto administrator:
Termin: $<% u s e r .deadline %> Nazwisko: <% user.name %>
Możliwe jest również zastosowanie układu strony do bloku znajdującego się wewnątrz dowolnego szablonu. <% # app/views/users/ c h i e f .h t m l .erb %> <% r e n d e r ( :layout > "administrator", ¡locals ^ c hi ef }) do %> Tytuł: <% chief.title %> <% end %>
Jak widać, tablica asocjacyjna : lo c a ls współdzielona jest pomiędzy szablonem częściowym a jego układem dokumentu.
Pamięć podręczna Umieszczanie w pamięci podręcznej jest tanim sposobem pozwa lającym na przyspieszenie wolnych aplikacji dzięki przechowywa niu wyników obliczeń, generowania oraz wywołań kierowanych do bazy danych pomiędzy poszczególnymi żądaniami. Action Con troller pozwala na trzy rozwiązania o różnym poziomie szcze gółowości: umieszczanie w pamięci podręcznej stron, akcji oraz fragmentów.
Umieszczanie stron w pamięci podręcznej Umieszczanie stron w pamięci podręcznej to rozwiązanie, w któ rym wszystkie dane wyjściowe akcji przechowywane są w pliku HTML, który serwer WWW może prezentować bez przejścia przez pakiet Action Pack. Może to być aż sto razy szybsze od procesu dynamicznego generowania treści. Niestety to niewiarygodne przy spieszenie jest dostępne jedynie dla stron bezstanowych, na których wszyscy odwiedzający traktowani są w ten sam sposób. Systemy zarządzania treścią, w tym błogi oraz wiki, zawierają wiele stron, które świetnie sprawdzają się w tym rozwiązaniu, jednak systemy oparte na kontach, w których użytkownicy logują się i przetwarzają własne dane, są gorszymi kandydatami do tego podejścia. Określenie, które akcje mają zostać umieszczone w pamięci pod ręcznej, odbywa się za pomocą metody caches page:
W idoki
| 117
class WeblogController < A c ti on Co nt ro ll er::Base caches page :show, :new end
Powoduje ona wygenerowanie w pamięci podręcznej plików, takich jak weblog/show/5 oraz weblog/new, odpowiadających adre sowi URL wykorzystywanemu do wywołania dynamicznej ge neracji. W ten sposób serwer jest w stanie pobrać plik znajdujący się w pamięci podręcznej, o ile on istnieje, a w innym przypadku pozwolić na przekazanie żądania do pakietu Action Pack w celu wygenerowania pliku. Wygaśnięcie pamięci podręcznej odbywa się poprzez usunięcie pliku w niej się znajdującego, co z kolei powoduje uruchomienie mechanizmu „leniwej regeneracji", w którym pamięć podręczna nie zostanie odbudowana, dopóki nie zostanie wykonane kolejne za pytanie skierowane do niej. API odpowiedzialne za to działanie naśladuje opcje metody url fo r i jej pokrewnych: class WeblogController < A c ti on Co nt ro ll er::Base def update L i s t .update(@params["l i s t "]["i d " ], @p a r a m s [ "l i s t "]) expire page :action > "show", :id > @p a r a m s [ "l i s t "] *#•[ "id"] redirect to :action > "show", :id > @p a r a m s [ "l i s t "] "id"] end end
Dodatkowo można wyczyścić pamięć podręczną za pomocą klas czyszczących typu sweeper, które działają na zmianach w modelu w celu ustalenia, kiedy pamięć podręczna powinna zostać opróż niona. Konfiguracja katalogu pamięci podręcznej. Katalog pamięci pod ręcznej powinien być katalogiem głównym serwera WWW i usta wiany jest za pomocą Base. page_cache_directory "/document/ ^ r o o t ". W przypadku Rails katalog ten został już ustawiony na RAILS_R00T + "/public".
118
|
Rails. Leksykon kie szo n ko w y
Konfiguracja rozszerzenia pamięci podręcznej. Domyślnym roz szerzeniem pamięci podręcznej jest Mml, dzięki czemu pliki w niej się znajdujące mogą z łatwością być pobrane przez serwer WWW. Jeśli wolimy wybrać inne rozszerzenie, na przykład .pkp czy .shtml, wystarczy ustawić B a se.page_cache_extension. Metody. Do umieszczania stron w pamięci podręcznej można wykorzystać następujące metody: cache_page(zaivartość n il , o p c je {}) Ręcznie umieszcza w pamięci podręcznej zawartość znajdu jącą się w kluczu wynikającym z opcji. Jeśli nie podano za wartości, wykorzystana zostanie treść ^response . body. Jeśli nie podano opcji, wykorzystane zostaną aktualne opcje dla tej akcji. Przykład: cache page "Jestem w pamięci podręcznej", e*"lists", :action > "show"
:controller
>
expire_page( o p c je {}) Powoduje wygaśnięcie w pamięci podręcznej strony z opcjami znajdującymi się w kluczu. Przykład: expire page :controller
> "lists",
:action
> "show"
Umieszczanie akcji w pamięci podręcznej Umieszczanie akcji w pamięci podręcznej jest podobne do umiesz czania tam stron ze względu na fakt, iż pełne dane wyjściowe odpowiedzi przechowywane są w pamięci. Różnica polega na tym, że każde żądanie nadal przechodzi przez pakiet Action Pack. Klu czową zaletą takiego rozwiązania jest to, że przed wyświetleniem danych z pamięci podręcznej uruchamiane są filtry, co pozwala na uwierzytelnienie i inne ograniczenia w zakresie tego, czy okre ślona osoba może zobaczyć zawartość znajdującą się w pamięci podręcznej.
W idoki
| 119
Przykład: class ListsController < ApplicationController before filter :authen ti ca te, :except > :public caches page :public caches action :show, :feed end
W powyższym przykładzie publiczna akcja nie wymaga uwierzy telnienia, dlatego można skorzystać z szybszej metody umieszcza nia strony w pamięci podręcznej. Akcje show oraz feed muszą jednak być ukryte za filtrem uwierzytelniającym, dlatego kod ten musi zostać zaimplementowany jako akcja umieszczana w pamięci podręcznej. Umieszczanie akcji w pamięci podręcznej wewnętrznie wykorzy stuje umieszczanie fragmentów w pamięci podręcznej oraz filtr. Pamięć podręczna fragmentu nazywana jest zgodnie z aktualnym hostem oraz ścieżką. Strona, do której dostęp można uzyskać pod adresem david.somewhere.eom/lists/show/l, da fragment o nazwie da.vid.somewhere.eom/lists/show/l. Pozwala to programowi umiesz czającemu dane w pamięci podręcznej na rozróżnienie adresów david.somewhere.com/lists/ oraz iamis.somewhere.com/lists/, co jest przy datnym sposobem obsługi wzorca „subdomena jako klucz konta".
Umieszczanie fragmentów w pamięci podręcznej Umieszczanie fragmentów w pamięci podręcznej wykorzystywane jest w połączeniu z wieloma blokami w ramach szablonów i po zwala uniknąć umieszczania w pamięci podręcznej całej akcji. Przydaje się to, kiedy pewne elementy akcji często się zmieniają lub uzależnione są od skomplikowanego stanu, podczas gdy inne zmieniają się rzadko lub mogą być współdzielone przez większą liczbę podmiotów. Umieszczanie fragmentów w pamięci podręcz nej odbywa się z wykorzystaniem metody pomocniczej dostępnej w Action View. Szablon z tym mechanizmem mógłby na przykład przypominać poniższy:
120
|
Rails. Leksykon kie szo n ko w y
< b >W it aj, <% Pname %> <% cache do %> Wszystkie tematy w systemie: <% render collection of partials "topic", Topic.find all %> <% end %>
Taka pamięć podręczna zostanie związana z nazwą akcji, która ją wywołała. Można by zatem wykorzystać exp ire_frag m en t( : ^ c o n tr o lle r > "to p ic s ", :actio n > " l i s t " ) do unieważ nienia jej gdybyśmy użyli kontrolera lub akcji. Nie jest to zbyt przydatne, jeśli potrzebne jest nam umieszczenie w pamięci pod ręcznej wielu fragmentów dla jednej akcji czy też jeśli sama akcja umieszczana jest tam za pomocą caches a ctio n . Zamiast tego można wzbogacić nazwę wykorzystanej akcji o przyrostek w stylu: <% cache(:action
> "list",
:action suffix
> "all topics") do %>
W rezultacie otrzymalibyśmy nazwę w stylu /topics/list/all topics, co nie pozostawałoby w konflikcie z żadną pamięcią podręczną akcji czy innym fragmentem korzystającym z odmiennego przy rostka. Warto zauważyć, że adres URL nie musi tak naprawdę istnieć czy też być możliwy do wywołania. Wykorzystujemy po prostu system url fo r do wygenerowania unikalnych nazw pa mięci podręcznych, do których można się później odnieść w celu wyczyszczenia ich. Wywołanie czyszczące dla tego przykładu miałoby formę expire_fragm ent ( : c o n t r o lle r > " t o p ic s " , :a ctio n > " l i s t " , : a c tio n _ s u ffix > " a ll _ t o p i c s " ). Przechowywanie fragmentów. By skorzystać z umieszczania frag mentów w pamięci podręcznej, musimy określić, gdzie ma ona być przechowywana. Robi się to poprzez przypisanie magazynu frag mentów, który może być jednego z czterech rodzajów: Filestore Przechowuje fragmenty na dysku w cache path, działa do brze dla wszystkich środowisk i współdzieli fragmenty po między wszystkie procesy serwera WWW działające w tym samym katalogu aplikacji.
W idoki
| 121
Memory Storę Przechowuje fragmenty w pamięci, co jest dopuszczalne dla WEBrick oraz FCGI (o ile nie ma dla nas znaczenia, że każdy proces FCGI ma swój własny magazyn fragmentów). Nie na daje się dla CGI, gdyż proces jest odrzucany na końcu każdego żądania. Potencjalnie może zająć dużą ilość miejsca w pamięci, gdyż każdy proces będzie przechowywał tam całą swoją pa mięć podręczną. DRbStore Przechowuje fragmenty w pamięci w osobnym, współdzielo nym procesie DRb. Działa to dobrze dla wszystkich środowisk i przechowuje tylko jedną pamięć podręczną dla wszystkich procesów, jednak wymaga uruchomienia osobnego procesu DRb i zarządzania nim. MemCacheStore Działa jak DRbStore, jednak korzysta z MemCache firmy Danga. Wymaga biblioteki ruby-memcache: gem i n s t a l l ruby memcache. Przykłady konfiguracji (domyślnie MemoryStore): A c ti on Co nt ro ll er::B a s e .fragment A c ti on Co nt ro ll er::B a s e .fragment e*"/path/to/cache/directory" A c ti on Co nt ro ll er::B a s e .fragment e*"druby:/ / l o ca lh os t:9192" A c ti on Co nt ro ll er::B a s e .fragment e*store, "localhost" A c ti on Co nt ro ll er::B a s e .fragment e*(" parameter")
cache storę cache storę
:memory storę :file storę,
cache storę
:drb storę,
cache storę
:mem cache
cache storę
M y O w n S t o r e .new
Czyszczenie pamięci podręcznej Klasy typu Sweeper to w świecie pamięci podręcznej synonim za kończenia, odpowiedzialny za wyczyszczenie pamięci, kiedy obiekty modeli się zmieniają. Są one po części klasami typu Observer, po części filtrami i implementują wywołania zwrotne dla obu ról. Przykład takiej klasy można znaleźć niżej:
122
|
Rails. Leksykon kie szo n ko w y
class ListSweeper < A c ti on Co nt ro ll er::C a c h i n g ::Sweeper observe List, Item def after save(record) list record.is a?(List) ? record : record.list expire page(:controller > "lists", ¡action > %w( show ‘■ ’►public feed ), :id > list.id) expire action(:controller > "lists", ¡action > "all") l i s t .shares.each { |share| expire page(:controller > ‘’►"lists", ¡action > "show", ¡id > share.url key) } end end
Klasa Sweeper przypisywana jest w kontrolerach, które chcą, by ich zadania wykonywane były z wykorzystaniem metody klasy cache_sweeper: class ListsController < ApplicationController caches action ¡index, ¡show, ¡public, ¡feed cache sweeper ¡list sweeper, ¡only > [ ¡edit, ‘■ ’►¡share ] end
¡destroy,
W powyższym przykładzie w pamięci podręcznej umieszczane są cztery akcje, a trzy akcje odpowiedzialne są za czyszczenie ich pamięci podręcznych.
Rails i Ajax Ajax to akronim od Asynchronous JavaScript and XML (asynchro niczny JavaScript i XML). Najważniejszą cechą charakterystyczną Ajaksa jest zwiększona interaktywność stron internetowych po zwalająca na interakcję z serwerem WWW w tle. Ma to na celu wzrost szybkości, funkcjonalności oraz użyteczności witryny. Rails zawiera platformę JavaScriptu o nazwie Prototype (http://www. prototypejs.org) oraz bibliotekę kontrolek i efektów wizualnych JavaScriptu o nazwie Scriptaculous (http://script.aculo.us). Jeśli chcemy korzystać z tych bibliotek oraz ich metod pomocniczych
Rails i A ja x
| 123
(ActionView::H e l p e r s ::PrototypeHelper oraz ActionView: Helpers: :ScriptaculousHelper), konieczne jest wykonanie
jednego z następujących kroków: Użycie <% javascript_include_tag :defaults %> w części HEAD strony (rozwiązanie zalecane) Funkcja ta zwraca odniesienia do plików JavaScriptu utwo rzonych przez polecenie Rails w katalogu public/javascripts. Rozwiązanie to jest polecane, gdyż przeglądarka może wtedy umieścić biblioteki w pamięci podręcznej, zamiast pobierać każdą funkcję na nowo przy każdym żądaniu. Użycie <% javascript_include_tag 'prototype' %> Jak powyżej, jednak uwzględnione zostaną jedynie pliki biblioteki Prototype, co oznacza, że będzie można korzystać z podstawowej funkcjonalności Ajaksa. W przypadku metod pomocniczych opartych na Scriptaculous, takich jak efekty wizualne, autouzupełnianie, przeciąganie i upuszczanie, po winno się korzystać z pierwszej metody. Użycie <% define_javascript_functions %> Powoduje skopiowanie wszystkich funkcji JavaScriptu we wnątrz pojedynczego bloku skryptu. Nie jest to rozwiązanie zalecane.
JavaScriptHelper Rails udostępnia funkcjonalność służącą do pracy z JavaScriptem w widokach za pośrednictwem metod pomocniczych, takich jak button_to_function(nazwa, funkcja,
opcje_html
{})
Zwraca odnośnik, który uruchomi funkcję w JavaScripcie za pomocą programu obsługi zdarzenia onclick. Przykłady: button to function "Greeting", "alert( 1Witaj, świecie!')" button to function "Delete", "if c o n f i r m ( 1Na p r a w d ę ? 1) e*f do d e l e t e O ; }"
124
|
Rails. Leksykon kie szo n ko w y
define _ j a v a sc rip t_ fu n ctio n s() Udostępnia biblioteki JavaScriptu z pakietu ActionPack we wnątrz pojedynczego znacznika
lin k _ to _ fu nction (nazwa, funkcja, opcje_html {}) Zwraca odnośnik wywołujący funkcję JavaScriptu, wykorzy stując do tego program obsługi zdarzeń onclick, i zwraca fa ls e po wykonaniu tego. Przykłady: link to function "Greeting", "a le rt ('W i t a j , świecie!')" link to f u nc ti on(image t a g ( "delete"), "if confirm e*( Naprawdę? ') { do d e l e t e O ; }")
PrototypeHelper PrototypeHelper udostępnia zbiór metod pomocniczych służących do wywołania funkcji JavaScriptu z biblioteki Prototype, w tym możliwość wywoływania metod zdalnych za pomocą Ajaksa. Oznacza to, że można wywoływać akcje w kontrolerach przez
Rails i A ja x
| 125
przeładowywania strony, jednak nadal uaktualniać pewne jej ele menty za pomocą wstawiania uaktualnień do DOM. Często spoty kanym przypadkiem wykorzystania jest formularz dodający nowy element do listy bez przeładowywania strony. Poniżej znajduje się lista metod pomocniczych: evaluate_remote_response() Zwraca eval(request.responseText), czyli funkcję JavaScriptu, którą może wywołać form_remote_tag w : complete
w celu wykonania analizy zwracanego dokumentu zawie rającego większą liczbę uaktualnień za pomocą wywołań update_element_function. form_remote_for(naziva_obie/
{}, &proc)
{}) Zwraca znacznik formularza, który zostanie przesłany za pomocą żądania XMLHttpRequest w tle zamiast zwykłego przeładowania strony z metodą POST. Choć do serializacji elementów formularza wykorzystany jest JavaScript, prze słanie formularza odbywa się z punktu widzenia strony otrzymującej dokładnie tak jak zwykle (wszystkie elementy dostępne są w tablicy Oparams). Opcje służące do określania miejsca docelowego za pomocą : url oraz definiowania wy wołań zwrotnych są takie same jak w link to remote.
form_remote_tag( o p c je
Miejsce docelowe dla przeglądarek nieobsługujących JavaScriptu można podać za pomocą opcji :action lub :method dla : html. Przykład: form remote tag :html > { :action > url for e*(:controller > "some", :action > "place") }
Tablica asocjacyjna przekazana do klucza :html jest odpo wiednikiem argumentu opcji podawanego jako drugi w me todzie FormTagHelper.form_tag.
126
|
Rails. Leksykon kie szo n ko w y
Domyślnie akcja rezerwowa jest taka sama jak podana w : ur 1 (a metodą domyślną jest : post). link_to_rem ote(naziva, o p c je { } , o p c je_ h tm l {}) Zwraca definiowany przez option s [ : u rl] (z wykorzystaniem formatu u rl fo r) odnośnik do akcji zdalnej wywoływanej w tle za pomocą XMLHttpRequest. Wynik tego żądania można następnie wstawić do obiektu DOM, którego identy fikator podaje się za pomocą o p tio n s[: update]. Zazwyczaj wynik będzie szablonem częściowym przygotowanym przez kontroler za pomocą render_partial bądź ren d er_p artial_ ^ c o lle c t io n . Przykłady: link to remote "Usuń ten wpis", :update > "posts", e»:url > { :action > "destroy", :id > post, id } link to remote(image tag("r ef re sh"), :update > emails", :url > { :action > "list emails" })
Można również podać tablicę asocjacyjną dla o p tio n s ^ [:u p d ate], by pozwolić na łatwe przekierowanie danych wyjściowych do innego elementu DOM, jeśli wystąpi błąd po stronie serwera. Przykład: link to remote "Usuń ten wpis", :url > { :action > e*-"d e st ro y", :id > post.id }, :update > { :success e»"posts", :failure > "error" }
>
Opcjonalnie można użyć parametru o p tio n s [: p o sitio n ] do wpłynięcia na sposób uaktualnienia docelowego elementu DOM. Musi on mieć wartość : before, :top, : bottom lub : a fte r . Domyślnie żądania zdalne przetwarzane są asynchronicznie i w tym czasie wywołanych może zostać wiele różnych wy wołań zwrotnych JavaScriptu (na przykład w przypadku
Rails i A ja x
| 127
pasków postępu). Wszystkie wywołania zwrotne otrzy mują dostęp do obiektu żądania przechowującego żądanie XMLHttp Request. By uzyskać dostęp do odpowiedzi serwera, należy użyć re q u e st. responseText. By uzyskać informację na temat statusu HTTP, należy użyć req u est, sta tu s. Przykład: link to remote word, :url > { :action ‘»word counter }, :complete > "undoRequestCompleted(request)"
> "undo",
:n
>
Wywołania zwrotne, jakie można podać, to (w kolejności): : loading Wywoływane, kiedy dokument zdalny ładowany jest danymi przez przeglądarkę. : loaded Wywoływany, kiedy przeglądarka zakończy ładowanie dokumentu zdalnego. : in te r a c tiv e Wywoływany, kiedy użytkownik może wejść w inte rakcję z dokumentem zdalnym, nawet jeśli nie skoń czył on się ładować. : success Wywoływany, kiedy żądanie XMLHttpRequest zosta nie zakończone, a kod statusu HTTP mieści się w za kresie 2XX. : f a ilu r e Wywoływany, kiedy żądanie XMLHttpRequest zosta nie zakończone, a kod statusu HTTP nie mieści się w zakresie 2XX.
128
|
Rails. Leksykon kie szo n ko w y
: complete Wywoływany, kiedy żądanie XMLHttpRequest zo stanie zakończone (uruchamiane po :su ccess lub : f a ilu r e , jeśli są one obecne). Wywołania : success oraz : fa ilu re można ulepszyć, dodając kolejne wywołania zwrotne dla określonych kodów statusu. Przykład: link to e*404 > e H J R L e*status
remote word, :url > { :action > "action" }, "alert('Nie znaleziono...? Niepoprawny adres : f a i l u r e > "alert('Błąd HTTP 1 + request. + ! 1)"
Wywołanie zwrotne dla kodu statusu nadpisuje programy obsługi zdarzeń : success lub : fa ilu re , jeśli są one obecne. Jeśli z jakiegoś powodu potrzebne jest nam przetwarzanie syn chroniczne, blokujące przeglądarkę na czas wykonywania żą dania, należy podać opcję o p tio n s[: type] : synchronous. Logikę wywoływania po stronie przeglądarki można dodat kowo dostosować do własnych potrzeb, przekazując frag menty kodu w JavaScripcie za pomocą opcjonalnych para metrów. W kolejności użycia będą to: : confirm Dodaje okno dialogowe z potwierdzeniem. : condition Zdalne żądanie wykonuje warunkowo. Należy wyko rzystać ten parametr do opisania warunków po stronie przeglądarki, mówiących, kiedy żądanie nie powinno być zapoczątkowane. : before Wywoływany przed zapoczątkowaniem żądania.
Rails i A ja x
| 129
: a fte r Wywoływany natychmiast po zapoczątkowaniu żąda nia, a przed : loading. : submit Określa identyfikator elementu DOM wykorzystanego jako element nadrzędny elementów formularza. Do myślnie jest to bieżący formularz, jednak równie dobrze może to być identyfikator wiersza tabeli czy innego elementu DOM. o b se rv e _ fie ld ( id e n t y fi k a t o r _ p o la , o p c je {}) Obserwuje pole o identyfikatorze DOM podanym za pomocą pierwszego parametru i wykonuje wywołanie oparte na Ajaksie, kiedy jego zawartość się zmieni. Wymagane opcje to jedna z dwóch poniższych możliwości: : url Opcje akcji do wywołania w momencie, gdy pole zostało zmienione, podane w stylu u rl fo r. : function Zamiast wykonywać wywołanie zdalne skierowane do adresu URL, można podać funkcję, jaka powinna być wywołana. Dodatkowe opcje to: : frequency Częstotliwość (w sekundach), z jaką wykrywane będą zmiany określonego pola. Nieustawienie tej opcji lub ustawienie jej na wartość mniejszą od lub równą zero spowoduje wykorzystanie obserwacji opartej na zda rzeniach zamiast obserwacji opartej na czasie.
130
|
Rails. Leksykon kie szo n ko w y
: update Określa identyfikator DOM elementu, którego atrybut innerHTML powinien zostać uaktualniony tekstem od powiedzi XMLHttpRequest. :with Wyrażenie w języku JavaScript określające parametry żądania XMLHttpRequest. Domyślnie przyjmuje war tość, która w analizowanym kontekście odnosi się do nowej wartości pola. Jeśli przekaże się łańcuch znaków bez znaku , zostanie rozszerzone w taki sposób, by oznaczać klucz formularza, do którego wartość powinna zostać przypisana. Kod :with > "term" daje 'term' rv a lu e ". Jeśli znak występuje, nie będzie miało miej sce rozszerzenie. : on Określa, który program obsługi zdarzeń należy obser wować. Domyślnie ustawiony jest na changed dla pól tekstowych oraz click dla przycisków opcji oraz pól wyboru. Dzięki tej opcji można wybrać zdarzenia biur, focus czy dowolne inne. Dodatkowo można podać dowolną opcję udokumentowaną w opisie link_to_rem ote. o b s e r v e _ fo r m ( id e n t y fik a t o r _ p o la , o p c je {}) Podobne do observe fie ld , jednak działa na całym formula rzu określonym za pomocą identyfikatora DOM pola. Opcje są takie same jak dla observe fie ld , jednak domyślna war tość opcji :with zwraca zserializowaną (łańcuch żądania) wartość formularza. p e rio d ica lly _ c a ll_ re m o te ( o p c je {}) Okresowo wywołuje podany adres URL co określoną liczbę sekund i uaktualnia podany element div wynikiem tego zdal nego wywołania. By podać liczbę sekund, należy przekazać
Rails i A ja x
| 131
opcję : frequency (domyślnie ma wartość 10). By określić adres URL, należy podać opcję : url. By określić identyfikato rem element div, który ma zostać uaktualniony wynikami, należy podać opcję : update z identyfikatorem docelowego elementu div. Na przykład: <% periodically call remote):url > 'update', e*-:frequency > '20', :update > 'my target div') %>
remote_form_for(naziva_obie/ "options", :url > { :action > e»:update options }) %>"> «option value "0">Witaj «option value "l">świecie
subm it_to_rem ote (nazwa, wartość, opcje {}) Zwraca znacznik input przycisku, który prześle formularz za pomocą żądania XMLHttpRequest w tle zamiast korzystania ze zwykłej metody POST. Argument opcji jest taki sam jak w form_remote_tag. u p d ate_elem ent_fu n c tio n ( i d e n t y f i k a t o r _ e l e m e n t u , opcje
{}, kblok)
Zwraca funkcję (lub wyrażenie) języka JavaScript uaktualnia jące element DOM zgodnie z przekazanymi opcjami: : content Treść wykorzystana do uaktualnienia elementu. Jeśli wykorzystuje się blok, można tę opcję opuścić.
132
|
Rails. Leksykon kie szo n ko w y
: action Poprawne opcje to : update (wartość domyślna), : empty oraz : remove. : p o sitio n Jeśli opcja : a ctio n ma wartość : update, opcjonalnie można podać jedną z następujących wartości: : before, :top, : bottom lub : a fte r . Przykłady: <% javascript tag(update element f u n c ti on ("products", e»:position > :bottom, :content > "
Nowy produkt! *»
")) %> <% replacement function update element function ‘»("products") do %>
Produkt l
Produkt 2
<% end %> <% javascript tag(replacement function) %>
Metodę tę można również wykorzystać w połączeniu z wy wołaniem zdalnej metody, gdzie wynik jest następnie ana lizowany w celu wprowadzenia większej liczby uaktualnień na stronie. Przykład: # Wywoływanie widoku
<% form remote tag :url > { ¡action > "buy" ^►¡complete > evaluate remote response %> tutaj wszystkie dane wejściowe...
update element f u nc ti on("c a r t ", ¡action > ¡update, position > ¡bottom, ¡content > "
Nowy produkt: ^ # { @ p r o d u c t .name}
")) %>
Rails i A ja x
| 133
<% update element fu nc ti on C" st at us ", :binding e»binding) do %> Kupiłeś nowy produkt! <% end %>
>
Warto zwrócić uwagę na to, że drugie wywołanie nie musi znajdować się w bloku danych wyjściowych ERb, ponieważ wykorzystuje ono blok w sposób bezpośredni i przekazuje wiązanie do bezpośredniego renderowania. Ta sztuczka działa jednak tylko z ERb (a nie obiektami Builder czy innymi for mami szablonów). update_page(&blo/<) Tworzy JavaScriptGenerator i zwraca wygenerowany kod języka JavaScript. Można to wykorzystać do uaktualnienia większej liczby elementów strony w odpowiedzi opartej na Ajaksie. Więcej informacji na ten temat znajduje się w pod rozdziale „JavaScriptGenerator". update_page_t ag (&blo/<) Działa jak update page, jednak opakowuje wygenerowany kod języka JavaScript w znacznik
Kod w naszym widoku to proste wywołanie Google Maps API za pośrednictwem biblioteki JavaScriptu, generujące mapę w elemencie div o identyfikatorze map. 3. Następnie należy uruchomić serwer WWW i otworzyć w przeglądarce stronę http:/Aocalhosi:3000/web services/geocode lookup.
Logowanie Klasa logger udostępnia proste w obsłudze, jednak dość zaawan sowane, jeśli chodzi o możliwości, narzędzie do logowania, z któ rego korzystać może każdy, ponieważ znajduje się ono w bibliotece standardowej Ruby 1.8.x. Dostęp do tej klasy można uzyskać z do wolnego miejsca w kodzie napisanym w Ruby i jest to świetne narzędzie służące do debugowania aplikacji. Rails automatycznie generuje plik logu odpowiadający określonemu środowisku i znajdujący się w folderze log. By móc logować komunikat z kontrolera lub modelu, należy uzy skać dostęp do instancji programu logującego Rails za pomocą metody logger. class ProductController < Ac ti on Co nt ro ll er::Base def index logger.info 'To mój komunikat end end
Lo go w an ie
| 165
Na zewnątrz kontrolera lub modelu można albo przekazać in stancję klasy logger, albo uzyskać do niej dostęp za pomocą Stałej RAILS_DEFAULT_LOGGER. Komunikaty różnią się poziomem (info, error i tak dalej), co od zwierciedla ich odmienne znaczenie. Poziomy oraz ich znaczenia omówione są poniżej: FATAL
Błąd, którego nie da się obsłużyć, powodujący zakończenie działania programu. ERROR
Błąd, który da się obsłużyć. WARN
Ostrzeżenie. INFO
Ogólna (przydatna) informacja dotycząca operacji systemowej. DEBUG
Niskopoziomowa informacja przeznaczona dla programistów. Każdy komunikat ma zatem swój poziom. Sam Logger również posiada poziom działający jak filtr, dzięki czemu możemy kontro lować ilość informacji emitowanych przez program logujący bez konieczności usuwania samych komunikatów. Przykładowo w przypadku systemu produkcyjnego można usta wić program logujący na poziom INFO (lub WARN, jeśli nie chcemy, by pliki logu coraz bardziej obrastały w powtarzające się informacje). Kiedy jednak rozwijamy aplikację, będziemy chcieli mieć wszystkie informacje dotyczące stanu wewnętrznego programu, a poziom logowania ustawimy na DEBUG. Przykład: logger.debug("Utworzono program logujący") logger.info("Program został uruchomiony") logger.warn("Nie mam nic do roboty!")
166
|
Rails. Leksykon kie szo n ko w y
begin File.each line(path) do |line| unless line ~ /"(\w+) (.*)$/ l o g .error("Wiersz ma zły format: #{line}") end end rescue > err l o g g e r .fatal("Przechwycono wyjątek; program zostaje ^zakończony") l o g g e r .fatal(err) end
Ponieważ poziom logowania ustawiony jest na WARN, zapisywane są jedynie ostrzeżenia, błędy oraz błędy krytyczne. Informacje ogólne oraz służące do debugowania są po cichu ignorowane.
Filtrowanie w rażliw ych parametrów Kiedy Rails otrzymuje żądanie, ActionController loguje jego para metry. Jest to bardzo przydatne w przypadku debugowania, jednak czasami lepiej byłoby ukryć parametry, takie jak hasła, przed logowaniem. Jest to możliwe dzięki istnieniu klasy filter_ ^parameter_logging: class Ap plicationController < Ac ti o n C o n t r o l l e r ::Base filter parameter logging :password end
Pow yższy kod spowoduje, że w artość param etru o nazwie password zostanie w logu zastąpiona za pom ocą [FILTEREDl.By odfiltrować większą liczbę param etrów , w ystarczy dodać je jako dodatkowe ar gum enty do filter parameter logging, rozdzielając przecinkami.
Tw orzenie dodatkowych programów logujących Czasami zamiast zapisywania informacji do domyślnego logu Rails wolimy zapisać je do osobnego pliku, który można wysłać pocztą elektroniczną czy pobrać z serwera.
Lo go w an ie
| 167
By tego dokonać, musielibyśmy utworzyć nową klasę rozszerzają cą klasę logger: # lib/archive_logger.rb
class ArchiveLogger < Logger def format message(severity, timestamp, progname, msg) "#{timestamp.to formatted s(:db)} #{severity} #{msg}\n" end end
By użyć nowej klasy ArchiveLogger, należy utworzyć jej instancję za pomocą File: logfile F i l e .o p e n ( 1/p at h/ to /a ud it.log 1, 'a') archive log Ar c h i v e L o g g e r .new(logfile)
Teraz można korzystać z nowego logu, wywołując na nim metody, jak na przykład archive_log.info message. Należy koniecznie pamiętać, że obiekt logfile nie przesyła komu nikatów do pliku automatycznie w sposób domyślny. Oznacza to, że kod musi wywołać metodę logfile .flush, by dane zostały zapisane do pliku. Alternatywnie można też ustawić logfile . ^•sync true w celu załączenia przesyłania danych do pliku.
Logowanie w konsoli Kiedy korzysta się z konsoli, nie zawsze widzimy wszystkie ko munikaty, które normalnie zostałyby dodane do logu Rails. By włączyć logowanie w konsoli, należy wpisać: Ac t i v e R e c o r d ::Base.logger = L o g g e r .new(STDOUT)
Więcej informacji na temat wykorzystywania klasy Logger można uzyskać w podcaście Ryana Batesa poświęconym temu zagadnieniu (,http://railscasts.com/episodes/56) lub w artykule Mike'a Naberezny'ego umieszczonym pod adresem http://maintainable.com/articles/rails logging tips.
168
|
Rails. Leksykon kie szo n ko w y
ActiveResource ActiveResource pozwala deklarować oraz wykorzystywać usługi sieciowe dzięki użyciu interfejsu zbliżonego do ActiveRecord. Jest również wykorzystywany do komunikacji pomiędzy dwoma apli kacjami Rails. By ActiveResource działał, usługa sieciowa musi: • rozumieć adresy URL zgodne z architekturą REST ; • odpowiadać na żądania pojedynczymi, zserializowanymi do postaci XML obiektami; • poprawnie korzystać z kodów statusu HTTP (404, jeśli żądany rekord nie może zostać odnaleziony, 433, jeśli walidacja nie powiedzie się, i tak dalej). Dla przykładu utworzymy prostą aplikację Rails zarządzającą ko lekcjami płyt DVD, a także kolejną aplikację uzyskującą dostęp do tej pierwszej za pośrednictwem ActiveResource. 1.Na początek tworzymy aplikację Rails o nazwie my_video_ ^library: rails my video library
2. W naszej nowej aplikacji Rails tworzymy rusztowanie dla dvd: ./script/generate scaffold dvd title¡string c r a t i n g :string des c r ip ti on:string
3. Teraz wykonujemy skrypty migracji: rake db:migrate
4. W kolejnym kroku uruchamiamy serwer na porcie 3000: ./script/server -p 3000
Teraz możemy przetestować aplikację, przechodząc w prze glądarce na stronę http:/Aocalhost:3000/dvds. Trzeba dodać ja kieś płyty DVD, by mieć do czego uzyskiwać dostęp z drugiej aplikacji.
A ctiveR esource
| 169
Skoro pierwsza aplikacja jest gotowa i działa, zajmijmy się utwo rzeniem drugiej, która będzie uzyskiwała do niej dostęp. 1.Tworzymy nową aplikację Rails o nazwie another library: rails another library
2 .Teraz tworzymy kontroler o nazwie my dvds: ./script/generate controller my dvds
3. Następnie czas utworzyć w pliku lib/dvd.rb klasę reprezentu jącą płytę DVD za pomocą ActiveResource: class Dvd < A c t i v e R e s o u r c e ::Base self.site "http ://lo ca lh os t:3 0 0 0 " # P o b ra n ie wszystkich p ły t D VD
dej self.all D v d .J i n d ( :all) end end
4. Wszystko gotowe. Pobierzmy teraz listę płyt DVD za pomocą kontrolera my dvds controller.rb: class MyDvdsController < ApplicationController dej index Odvds Dv d.all end end
oraz z widokiem app/views/index.html.erb: <% Odvds.each do |dvd %> <% dvd.title %> <% dvd.rating %> <% d v d .description %>
<% end %>
5.Pora uruchomić serwer na porcie 3001: ./script/server -p 3001
6. Teraz należy otworzyć kolejne okno przeglądarki i przejść do strony http:/Aocalhost:3001/my dvds. Jeśli w pierwszej aplikacji dodaliśmy jakieś płyty DVD, powinniśmy je tutaj zobaczyć.
170
|
Rails. Leksykon kie szo n ko w y
Dodatki Dodatki (wtyczki, pluginy) Rails są rozszerzeniami lub modyfika cjami podstawowej platformy Rails. Dodatki pozwalają programi stom współdzielić kod bez wpływania na jego stabilną podstawę. By zobaczyć listę repozytoriów dodatków, można użyć: ./script/plugin discover
By dodać adres URL repozytorium dodatków, należy wpisać: ./script/plugin source [URL]
By usunąć repozytorium dodatków, należy wpisać: ./script/plugin unsource [URL]
By zainstalować dodatek w naszej aplikacji Rails, należy wpisać: ./script/plugin install [nazwa dodatku lub je go adres U R L ]
By wygenerować dokumentację dla dodatków, można użyć: rake rdoc:plugins
Powyższe polecenie powoduje utworzenie plików dokumentacji w formacie HTML znajdujących się w katalogu doc/plugins. By dowiedzieć się więcej na temat dodatków, w tym dostępnych dodatków, jakie można zainstalować we własnych aplikacjach, warto się udać na jedną z poniższych stron: • http://agilewebdevelopment.com/plugins, • http://wiki.rubyonrails.org/rails/pages/Plugins.
Capistrano Capistrano to samodzielne narzędzie wykorzystywane do auto matyzacji zadań za pośrednictwem SSH lub serwerów zdalnych. Zostało utworzone przez Jamisa Bucka (http://jamisbuck.org) i roz winięte, by wspomóc proces zarządzania wdrażaniem aplikacji.
Dodatki
| 171
Capistrano, podobnie jak Rails, używa zadań. Zadania mogą za wierać polecenia wykonywane na serwerach. Dodatkowo można definiować role dla serwerów i przypisywać określone zadania dla konkretnych ról. Jednym z nieporozumień związanych z Capistrano jest to, gdzie należy instalować to narzędzie. Ponieważ Capistrano wykonuje polecenia za pośrednictwem SSH, narzędzie to musi być zainsta lowane jedynie na maszynach, z których uruchamia się serwer. Capistrano to gem, który można zainstalować za pomocą następu jącego kodu: sudo gem install capistrano
By móc wykorzystywać Capistrano w aplikacji Rails, niezbędne są dwa pliki. Pliki te można wygenerować za pomocą skryptu capify. Jeśli jesteśmy już w folderze głównym Rails, można użyć: $ capify . [add] writing ' ./Capfile [add] writing ' ./c on fi g/ de pl oy.rb [done] capified!
By zobaczyć dostępne zadania, należy wpisać: cap -T
By zobaczyć szczegółowe opisy określonego zadania, można użyć polecenia: cap - e [ z a d a n i e ] # Przykład: cap -e deploy:cold
Domyślne zadania są następujące (i mogą być wykonywane za pomocą cap Iz a d a n ie l): deploy
Wdraża projekt. Wywołuje zarówno update, jak i restart. Warto zauważyć, że działa to jedynie dla aplikacji, które zo stały już kiedyś wdrożone. Dla wdrożenia typu cold konieczne będzie zapoznanie się z zadaniem deploy: cold, które odpo wiedzialne jest za wdrożenie w tych warunkach.
172
|
Rails. Leksykon kie szo n ko w y
de p l o y :check
Testuje zależności wdrożenia. Sprawdza rzeczy takie jak pra wa do katalogów czy niezbędne narzędzia, zgłaszając kwestie, które wydają się być nie w porządku lub których brakuje. Zadanie to przydaje się do sprawdzenia przed wykonaniem cap deploy, że wdrożenie ma szansę działać. d e p l o y :cleanup
Oczyszcza starsze opublikowane wersje. Domyślnie na każ dym serwerze przechowywanych jest ostatnich pięć wydań (choć można to ustawienie zmienić za pomocą zmiennej keep releases). Wszystkie pozostałe wersje wdrożeń są usu wane z serwerów. Domyślnie wykorzystuje polecenie su do do oczyszczenia starych wersji, jeśli jednak w określonym śro dowisku polecenie to jest niedostępne, należy ustawić zmienną :use_sudo variable na false. d e p l o y :cold
Wdraża i uruchamia „zimną" aplikację. Przydaje się, jeśli nigdy wcześniej nie wdrażaliśmy aplikacji lub jeśli aplikacja ta z jakiegoś powodu aktualnie nie działa. Powoduje wdro żenie kodu, wykonanie oczekujących migracji, a następnie, zamiast wywoływać zadanie d e p l o y :restart, wywołuje deploy: start w celu uruchomienia serwerów aplikacji. d e p l o y :migrate
Wykonuje zadanie migrate Rake. Domyślnie wykonuje je w ostatniej wdrożonej wersji aplikacji. Można jednak podać inną wersję dzięki zmiennej migrate target, która musi mieć wartość : latest (dla zachowania domyślnego) lub : current (dla wersji wskazanej przez dowiązanie symboliczne current). Zamiast symboli dla tych wartości można również użyć łań cuchów znaków. Można także podać dodatkowe zmienne środowiskowe do przekazania do Rake za pomocą zmiennej migrate env. Możliwe jest również podanie pełnej ścieżki do pliku wykonywalnego Rake dzięki ustawieniu zmiennej Rake. Wartości domyślne są następujące:
Wdraża oraz wykonuje oczekujące migracje. Działa podobnie do zadania deploy, jednak przed uaktualnieniem dowiązania symbolicznego wykonuje również oczekujące migracje (za pomocą zadania d e p l o y :migrate). Uaktualnienie nie jest w tym przypadku atomiczne, a transakcje nie zostają wy korzystane, ponieważ nie istnieje gwarancja, że migracje będzie się dało odwrócić. de p l o y :pending
Wyświetla zmiany powstałe od czasu ostatniego wdrożenia i przydaje się do ich podsumowania. Może nie być obsługi wane we wszystkich systemach kontroli wersji. deploy:pending:diff
Wyświetla diff, czyli różnice pomiędzy nowymi zmianami a ostatnim wdrożeniem. Przydaje się do sprawdzenia, jakie zmiany zostaną wdrożone. Może nie być obsługiwane we wszystkich systemach kontroli wersji. de p l o y :restart
Powoduje ponowne uruchomienie aplikacji. Zadanie to działa dzięki wywołaniu skryptu script/process/reaper pod bieżącą ścieżką. Domyślnie zostanie wywołane przez su do jako użytkownik app. Jeśli chcemy wykonać to zadanie jako inny użytkownik, należy ustawić zmienną :runner na tego użytkownika. Jeśli znajdujemy się w środowisku, w którym nie można skorzy stać z su do, konieczne jest ustawienie zmiennej : u s e s u do na false za pomocą polecenia: set :use sudo, Jalse
174
|
Rails. Leksykon kie szo n ko w y
de p l o y :rollback
Przywraca kod do poprzedniej wersji i ponownie go uru chamia. Przydaje się, jeśli kiedykolwiek odkryjemy, że wdro żyliśmy kod z błędami. Wystarczy zastosować polecenie cap rollback i wracamy do punktu wyjścia, czyli poprzed nio wdrożonej wersji. d e p l o y :rollback_code
Przywraca kod do poprzedniej wersji. Dowiązanie symbo liczne current zostanie uaktualnione tak, by wskazywało na poprzednio wdrożoną wersję, a następnie aktualna wersja zostanie usunięta z serwerów. Zamiast tego najczęściej wy korzystuje się zadanie rollback, gdyż uruchamia ono po nownie aplikację. d e p l o y :setup
Przygotowuje jeden lub większą liczbę serwerów do wdro żenia. Zanim możemy użyć w projekcie któregokolwiek z zadań Capistrano związanych z wdrożeniami, musimy upewnić się, że wszystkie serwery zostały przygotowane, stosując polecenie cap deploy:setup. Kiedy dodajemy nowy serwer, możemy z łatwością wykonać zadanie setup tylko na nim, określając zmienną środowiskową HOSTS: cap HOSTS new.server.com deploy:setup
Wykonanie tego zadania na serwerach, które zostały już skon figurowane, jest pełni bezpieczne. Nie spowoduje zniszczenia żadnych wdrożonych wersji czy danych. d e p l o y :start
Uruchamia serwery aplikacji. Próbuje wywołać skrypt apli kacji o nazwie script/spin, który musi wiedzieć, jak uruchomić metody nasłuchujące aplikacji. W przypadku aplikacji Rails skrypt ten może wywoływać script/process/spawner z odpo wiednimi argumentami.
Cap istran o
| 175
Domyślnie skrypt ten zostanie wykonany za pomocą su do jako użytkownik app. Jeśli chcemy wykonać to zadanie jako inny użytkownik, należy ustawić zmienną : run ner na tego użyt kownika. Jeśli znajdujemy się w środowisku, w którym nie można skorzystać z su do, konieczne jest ustawienie zmiennej :use_sudo na false. d e p l o y :stop
Zatrzymuje serwery aplikacji. Zadanie to wywołuje skrypt script/process/reaper dla procesu Spawner i wszystkich pro cesów aplikacji, jakie zostały wygenerowane. Tym samym jest to rozwiązanie typowe dla Rails i w innych systemach może istnieć konieczność nadpisania go. Domyślnie skrypt ten zostanie wykonany za pomocą su do jako użytkownik app. Jeśli chcemy wykonać to zadanie jako inny użytkownik, należy ustawić zmienną : run ner na tego użytkownika. Jeśli znajdujemy się w środowisku, w którym nie można skorzystać z su do, konieczne jest ustawienie zmien nej : use_sudo na false. de p l o y :symlink
Uaktualnia dowiązanie symboliczne na ostatnio wdrożoną wersję. Capistrano działa, umieszczając każdą nową wersję aplikacji w osobnym katalogu. Po wdrożeniu nowej wersji rolą tego zadania jest uaktualnienie dowiązania symbolicz nego current w taki sposób, by wskazywało na nową wersję. Rzadko istnieje konieczność bezpośredniego wywołania tego zadania. Zamiast tego należy użyć zadania deploy (wykonu jącego pełne wdrożenie wraz z ponownym uruchomieniem) bądź update (wykonującego wszystko z wyjątkiem ponow nego uruchomienia). de p l o y :update
Kopiuje projekt oraz uaktualnia dowiązanie symboliczne. Wy konuje to w transakcji, dlatego jeśli zadania update code lub symlink zawiodą, wszystkie zmiany wprowadzone na
176
|
Rails. Leksykon kie szo n ko w y
serwerach zdalnych zostaną przywrócone, pozostawiając system w takim samym stanie, w jakim był przed wywoła niem zadania update. Zazwyczaj zamiast update wywołuje się deploy, jednak update może przydać się, jeśli chcemy apli kację wdrożyć, jednak nie od razu uruchamiać ponownie. d e p l o y :update_code
Kopiuje projekt na serwery zdalne. Jest to pierwszy krok każdego wdrożenia przeniesienie uaktualnionego kodu oraz zasobów na serwery wdrożeniowe. Rzadko wywołuje się to zadanie w sposób bezpośredni. Zamiast niego powinno się wywołać zadania deploy (by wykonać pełne wdrożenie) lub update (jeśli chcemy osobno wykonać zadanie restart). Należy się upewnić, że zmienna :scm została ustawiona na wykorzystywany system kontroli wersji (domyślnie ma war tość : subversion), a zmienna :deploy_via na strategię wdro żenia,jakiej chcemy użyć (domyślnie ma wartość ¡checkout). de p l o y :upload
Kopiuje pliki do aktualnie wdrożonej wersji. Przydaje się do częściowego uaktualniania plików, na przykład kiedy po trzebna jest nam szybka zmiana pojedynczego pliku. Niektóre pliki, takie jak uaktualnione szablony, obrazki oraz arkusze stylów, mogą nie wymagać pełnego wdrożenia i w szczegól ności w pilnych sytuacjach wygodne może być szybkie wgra nie uaktualnień do wersji produkcyjnej. By użyć tego zadania, należy podać pliki i katalogi, które chcemy skopiować, jako listę rozdzieloną przecinkami w zmiennej środowiskowej FILES. Wszystkie katalogi zostaną przetworzone w sposób rekurencyjny, a pliki wgrane na serwery zdalne. Wszystkie pliki lub katalogi zaczynające się od znaku „ ." zostaną zignorowane. cap d e p l o y :upload FILES te m p l a t e s ,c o nt ro ll er.rb
Cap istran o
| 177
de p l o y :web:disable
Wyświetla użytkownikom stronę tymczasową. Wyłącza in terfejs webowy aplikacji, zapisując plik maintenance.html na każdym serwerze WWW. Serwery muszą być skonfigurowane tak, by wykrywać obecność tego pliku i, jeśli jest on obecny, zawsze go wyświetlać zamiast wykonywania żądania. Domyślnie strona tymczasowa poinformuje użytkowników, że na witrynie wykonywane są prace administracyjne („ma intenance"), które wkrótce („shortly") zostaną zakończone, jednak można te komunikaty zmodyfikować, podając zmienne środowiskowe REASON (przyczyna) oraz UNTIL (do kiedy): cap de pl o y : w e b :disable \ REASON "hardware upgrade" \ UNTIL "12pm Central Time"
Dalsze dostosowanie komunikatów do własnych potrzeb wymaga napisania własnego zadania. d e pl oy :w eb:enable
Sprawia, że dostęp do aplikacji zostaje wznowiony. Usuwa stronę maintenancehtml wygenerowaną przez zadanie deploy: ^ w e b :disable, co (o ile serwery zostały poprawnie skonfigu rowane) spowoduje, że aplikacja znowu stanie się dostępna. invoke
Wywołuje pojedyncze polecenie na serwerach zdalnych. Przydaje się do wykonywania rzadziej stosowanych poleceń, które mogą nie wymagać tworzenia dla nich pełnych zadań. Wystarczy za pomocą zmiennej środowiskowej COMMANDpodać polecenie, które ma być wykonane. By wykonać polecenie je dynie dla określonych ról, należy w rozdzielonej przecinkami liście ról będącej wartością zmiennej środowiskowej ROLES podać wybrane role. Alternatywnie można podać zmienną środowiskową HOSTS jako rozdzieloną przecinkami listę hostów, na których zadania mają zostać wykonane. Wreszcie jeśli chcemy wykonać polecenie za pośrednictwem su do, należy podać niepustą wartość dla zmiennej środowiskowej SUDO.
178
|
Rails. Leksykon kie szo n ko w y
Przykład użycia: cap COMMAND uptime HOSTS f o o .Ca pi s t r a n o .test invoke cap ROLES app.web SUDO 1 COMMAND "tail -f /var/log/ s*messages" invoke
shell
Rozpoczyna sesję interaktywną Capistrano. Udostępnia nam interaktywny terminal, w którym można wykonywać zadania i polecenia na wszystkich serwerach. Ostrzeżenie Zadanie shell jest nadal opcją eksperymentalną i może zo stać zmodyfikowane bez ostrzeżenia.
Więcej informacji na temat konfiguracji oraz użycia Capistrano w połączeniu z aplikacjami Rails można uzyskać na stronie http://capify.org.
TextMate Kiedy aplikacje Rails tworzy się w systemie Mac OS, najlep szym wyborem jest użycie edytora TextMate firmy MacroMates (http://macromates.com). W tabeli 1.4 znajduje się kila przydatnych skrótów klawiaturowych. Tabela 1.4. Skróty klawiaturowe edytora TextMate Skrót
O pis
Skrót
ST
Menu File
*\
O ST
Menu Method
-c S T
Menu Bundle
O pis Testowanie nowego menu Pokazanie fikstury
SR, SO R
Nazwy modelu
TextM ate
| 179
Tabela 1.4. Skróty klawiaturowe edytora TextMate
ciąg dalszy
Skrót
O pis
Skrót
O pis
»ft
Menu Rails
d e f ( t |tp)
Wykonanie testu
ft-cS -cS
Menu Navigation
a s ( e|m |d |. . .)
Metoda lub test
Nawigacja
ft. ff. f f e
Metoda
m co l
Utworzenie
f-
Asercje
*ft<
Znacznik ERb
kolumny tabeli t.
Utworzenie ładnej kolumny
hm, ho, hmt, b t
Powiązania modeli
»ftłł
Utworzenie szablonu częściowego z zaznaczonego fragmentu
v< a|u|c |p |f n |e11 1i)
Walidacje
» ftS S
Pokazanie
r p ( c |o |s 11 )
W ygenerowanie szablonu częściowego lin k
schematu
l i (p|pp|np|a |c |m |...)
to
f ina, f inf, f ini
Odszukiwanie
<3
Klawisz Delete
modeli
*P
p a ra m s [: id ]
Klawisz Control
rest
Blok re s p o n d to
Klawisz Option
wants
B lo k w a n ts
Klawisz
defcreat
Akcja c r e a t e
Command
ft
Klawisz Shift
rea
Przekierowanie
rp(c|o|s|1)
Trasy
Klawisz Return
Sft{
Przełączanie { }
Klawisz Enter
oraz d o -e n d
(fn+Return)
180
|
Rails. Leksykon kie szo n ko w y
Klawisz Escape
Metody pomocnicze Metody pomocnicze lub metody pomocnicze widoków są mo dułami dostępnymi do użycia w widokach. Udostępniają skróty do najczęściej wykorzystywanych fragmentów kodu. Poniżej znajduje się lista najpopularniejszych modułów pomocniczych wraz z ich metodami.
ActiveRecordHelper Moduł ActiveRecordHelper ułatwia tworzenie formularzy dla rekordów przechowywanych w zmiennych instancji. Udostępnia on następujące metody pomocnicze:
error message on error_message_on(obiekt, metoda, tekst_dodawany_z_przodu tekst_dodawany_z_tyłu klasa_css "formError")
Zwraca łańcuch znaków z elementem div zawierającym wszystkie komunikaty o błędach dla obiektów znalezionych jako zmienne instancji o podanych nazwach. Przykład <% error message on "post", "title" %> #
nie może być pusty
<%
error message on "post", "title", "Tytuł po prostu ", (bo nie będzie działał).", "inputError" %> #
Tytuł po prostu nie może być pusty ‘’►(bo nie będzie działał) .
M etody pom ocnicze
| 181
error messages for error_messages_for(*parame try)
Zwraca łańcuch znaków z elementem div zawierającym wszystkie komunikaty o błędach dla obiektów znalezionych jako zmienne instancji o podanych nazwach. Element div można dostosować do własnych potrzeb za pomocą następujących opcji: header_tag
Wykorzystany jako nagłówek elementu div z błędami (do myślnie ma wartość h2). id
Identyfikator elementu div z błędami (domyślnie ma wartość error Explan at ion). class
Klasa elementu div z błędami (domyślnie ma wartość error ^Explanation). obj ect
Obiekt (lub tablica obiektów), dla których należy wyświe tlać błędy, jeśli konieczne jest uniknięcie konwencji zwią zanej ze zmiennymi instancji. obj ect_name
Nazwa obiektu używana w nagłówku lub inny preferowany tekst. Jeśli opcja object name nie zostanie ustawiona, użyta zostanie nazwa pierwszego obiektu. header_message
Komunikat z nagłówka elementu div z błędami. By całkowi cie pominąć komunikat z nagłówka, należy przekazać nil lub pusty łańcuch znaków (domyślnie ma wartość X errors prohibited this object from being saved).
182
|
Rails. Leksykon kie szo n ko w y
message
Wyjaśnienie komunikatu pojawiające się po komunikacie nagłówka, a przed listą błędów. By całkowicie pominąć wy jaśnienie, należy przekazać nil lub pusty łańcuch znaków (domyślnie ma wartość There were problems with the following fields:).
form form ( nazwa_rekordu, opcje block_given?| ...}
{}) { |contents if
Zwraca pełny formularz ze wszystkimi niezbędnymi znacznikami input dla określonego obiektu Active Record. Przykład
Powiedzmy, że mamy model Article z atrybutem o nazwie title i typie VARCHAR oraz ciele o typie TEXT: fo rm ("post")
Otrzymamy wtedy:
'/post/create'
method
'p o s t '>
< / P>
M etody pom ocnicze
| 183
'submit'
value
'Utwórz'
/>
input in pu t(nazwa_rekordu, metoda, opcje
{})
Zwraca domyślny znacznik input dla typu obiektu zwracanego przez metodę. Przykład
Powiedzmy, że mamy model z atrybutem title o typie VARCHAR, a instancja przechowuje tekst „Witaj, świecie!": input( "p os t", "title") #
AssetTagHelper Moduł ten udostępnia metody służące do generowania kodu HTML łączącego widoki z zasobami, takimi jak obrazki, skrypty, arkusze stylów czy subskrybowane kanały RSS. Metody te nie weryfikują istnienia zasobów przed utworzeniem połączenia. Udostępnia on następujące metody pomocnicze:
im agepath image_path(źródło)
Oblicza ścieżkę do obrazka znajdującego się w publicznym katalogu obrazków. Przekazane zostaną pełne ścieżki z katalogu głównego dokumentu. Wykorzystywana wewnętrznie przez metodę imag e t ag do utwo rzenia ścieżki do obrazka.
184
|
Rails. Leksykon kie szo n ko w y
Przykłady image image image image
pathC'edit") p a t h ("e d i t .p n g ") p a t h ("i c on s/ ed it.pn g " ) p a t h ("/ico ns /e di t.p n g " )
# # # #
> > > >
/images/edit /i ma ge s/ ed it.png /i ma ge s/ ic on s/ ed it.png /i co n s / e d i t .png
im agetag image_tag(źródło,
o p c je
{})
Zwraca znacznik HTML obrazka dla podanego źródła. Źródłem może być pełna ścieżka lub plik istniejący w publicznym katalogu obrazków. Opcje :alt
Jeśli nie podano tekstu alternatywnego, użyta zostanie część nazwy pliku źródła (napisana z dużej litery i bez rozszerzenia). :size
Wielkość podana jako { S z ero k o ść}x {W y so k o ść}, przez co 30x45 daje width 30 i height 45. Opcja : size zostanie zigno rowana, jeśli wartości podane są w niewłaściwym formacie. :mouseover
Ustawia alternatywny obrazek wykorzystywany w momencie uruchomienia zdarzenia onmouseover oraz określa, że orygi nalny obrazek ma zostać podstawiony przy zdarzeniu onmouseout. Można wykorzystać tę opcję do zaimplementowania prostego przełączania obrazków w momencie, gdy wskaźnik myszy znajdzie się nad grafiką. Przykłady image t a g ( "icon") # image t a g ( "i co n.pn g " ) #
M etody pom ocnicze
| 185
image tag("icon.png", ¡size > "15x10", ¡alt > "Edit Entry") # image t a g ( "/ i co ns /i co n.g i f ", ¡size > "15x15") # image ta g("/icons/icon.g i f", ¡height > '32', ¡width > '32') # image t a g ( "/ i co ns /i co n.g i f ", ¡class > "menu icon") # image tag("mouse.png", ¡mouseover > "/images/mouse over.png") # image t a g ( " m o u s e .p n g " , ¡mouseover > image pathC'mouse ‘► o v e r .p n g " )) #
javascript indude tag javascrip t_in c1u d e_ta g ( * ź i ó d ł a )
Zwraca znacznik HTML s c r ip t dla każdego z podanych źródeł. Przykłady javascript include tag "xmlhr" # javascript include tag "xmlhr.js" # javascript include tag "common.javascript", "/elsewhere/cools" #
186
|
Rails. Leksykon kie szo n ko w y
# src "/j av as cr ip ts /c om mo n.j a v a s c r i p t "> # javascript include tag "http://www.railsapplication.com/xmlhr" #
# src "h t t p :// www.railsapplication.com/xmlhr.j s"> javascript include tag "http://www.railsapplication.com/xmlhr.js" #
# src "h t t p :// www.railsapplication.com/xmlhr.js "> javascript include tag ¡defaults # # # .. . #
style sh ee tlin kta g stylesheet_link_tag ( * ź r ó d ła )
Zwraca znacznik link z arkuszem stylów dla źródeł przekazanych jako argumenty. Jeśli nie określimy rozszerzenia, automatycznie dołączone zostanie .css. Atrybuty znacznika link można mody fikować, przekazując tablicę asocjacyjną jako ostatni argument. Przykłady stylesheet link tag "style" # < 1 ink href "/ s ty le sh ee ts /s ty le.c s s " # media "screen" rei "stylesheet" type "text/css" /> stylesheet link tag "style.css" # stylesheet link tag "http://www.railsapplication.com/style.css" #
M etody pom ocnicze
| 187
#
media "screen" rel "stylesheet" type "text/css" />
stylesheet link tag "style", :media > "all" # < 1 ink href "/ s ty le sh ee ts /s ty le.c s s " # media "all" rel "stylesheet" type "text/css" /> stylesheet link tag "style", :media > "print" # stylesheet link tag "random.styles", "/css/stylish" # #
CacheHelper Moduł CacheHelper udostępnia metodę służącą do umieszczania fragmentów widoku w pamięci podręcznej. Metoda ta została opisana poniżej.
cache cacheCnazwa
{}, kblok)
Metoda służąca do umieszczania w pamięci podręcznej fragmen tów widoku zamiast całej akcji czy strony. Technika ta przydaje się w przypadku elementów takich jak menu, listy tematów wiado mości czy fragmenty statycznego kodu HTML. Metoda ta przyj muje blok mieszczący w sobie zawartość, jaką chcemy umieścić w pamięci podręcznej. Przykłady # U m ieszczenie szablonu częściow ego w p a m ię c i p od ręczn ej
<% cache do %> <% render :partial <% end %>
188
|
> "menu" %>
Rails. Leksykon kie szo n ko w y
# U m ieszczenie statycznej treści w p a m ię c i p od ręczn ej
<% cache do %>
Witajcie, <% end %>
użytkownicy! Witamy na naszej stronie!
# U m ieszczenie w p a m ię c i p od ręczn ej treści statycznej p om iesz an ej z dynamiczną
<% cache do %> T ematy: <% render ¡partial > "topics", ¡collection ^a topic list %> Tematy w kolejności alfabetycznej <% end %>
>
DateHelper Moduł DateHelper tworzy przede wszystkim znaczniki select oraz option dla różnych typów dat oraz elementów dat. Wszystkie metody typu select współdzielą pewną liczbę opcji, które są następujące: :prefix
Nadpisuje domyślny przedrostek date wykorzystywany do wybierania nazwy. Podanie birthday po przekazaniu do metody select_month da nam birthday[month] zamiast date[month]. :include_blanl<
Ustawiane na true, jeśli musi istnieć możliwość ustawienia pustej daty. :discard_type
Ustawiane na true, jeśli chcemy zignorować część z typem wybranej nazwy. Jeśli ustawimy tę opcję na true, metoda select month użyje po prostu date (co można nadpisać za pomocą opcji : prefix) zamiast date[month]. Moduł DateHelper udostępnia następujące metody pomocnicze:
Zwraca zbiór znaczników select (po jednym dla roku, miesiąca, dnia, godziny oraz minuty) wybranych w celu uzyskania dostępu do określonego atrybutu czasu (identyfikowanego przez metodę) dla obiektu przypisanego do szablonu (identyfikowanego przez obiekt). Przykłady # G eneruje znacznik s elec t czasu, który p o zastosow aniu m etody PO ST # zostan ie p rzechow an y w atrybucie written_on zm iennej post.
datetime se le ctC"post", "written on") # G eneruje znacznik s elec t czasu z rokiem rozpoczynający s ię na # roku 1995, który p o zastosow aniu m etody PO ST zostan ie #przechow any w atrybu cie written_on zm iennej post.
datetime se le ctC"post", "written on",
:start year
> 1995)
# G eneruje znacznik s elec t czasu z dom yślną w artością 3 dni o d # aktualnej daty, który p o zastosow aniu m etody PO ST zostan ie #przechow any w atrybu cie departing zm iennej trip.
datetime selectC"trip", "departing",
:default
> 3.days.from now)
# G eneruje znacznik s elec t czasu ignorujący typ, który # p o zastosow aniu m etody PO ST zostan ie przechow any # w atrybu cie written_on zm iennej p o s t .
datetime se le ctC"post", "written on",
:discard type
> true)
d ista n c e o ftim e in w o rd s distance_of_time_in_words(od_czasu, z_sekundami false)
do_czasu
0,
Zwraca przybliżoną odległość w czasie w sekundach pomiędzy dwoma obiektami Time lub Date bądź liczbami całkowitymi.
190
|
Rails. Leksykon kie szo n ko w y
Przykłady from time Time.now distance of time in words(from time, from time + 50.minutes) # about 1 hour distance of time in words(from time, # about 1 hour
50.m i n u t e s .from now)
distance of time in words(from time, from time + 15.seconds) # less than a minute distance of time in words(from time, from time + 15.seconds, ^true) # less than 20 seconds distance of time in words(from time, # over 3 years
3.years.from now)
distance of time in words(from time, from time + 50.hours) # about 3 days distance of time in words(from time, from time + 4 5 .seconds, ^true) # less than a minute distance of time in words(from time, from time - 4 5 .seconds, true) # less than a minute distance of time in words(from time, # 1 minute
75.s e c o n d s .from now)
distance of time in words(from time, from time + l.year + ^ 3 . days) # about 1 year to time Time.now + 5.years + 19.days distance of time in words(from time, to time, true) # over 5 years distance of time in words(to time, from time, true) # over 5 years distance of time in w o r d s ( T i m e .now, Time.now) # less than a minute
M etody pom ocnicze
| 191
selectdate select_date(data
Date.today,
opcje
{})
Zwraca zbiór znaczników select języka HTML (po jednym dla roku, miesiąca oraz dnia) wybranych za pomocą daty. Można w jawny sposób ustawić kolejność znaczników za pomocą opcji : order połączonej z tablicą symboli dla roku (:year), miesiąca (:month) oraz dnia (:day) w pożądanej kolejności. Jeśli żaden symbol nie zostanie przekazany, zostanie on dodany na końcu przekazanej opcji : order. Przykłady my date
Time.today + S.days
# G eneruje znacznik s elec t daty z w artością dom yślną b ęd ą c ą # datą z m y jd a te (sześć dni o d dzisiaj).
select date(my date) # G eneruje znacznik s elec t daty z w artością dom yślną rów ną dzisiaj.
select d a t e ( ) # G eneruje znacznik s elec t daty z w artością dom yślną b ę d ą c ą datą # z m y jd a te (sześć dni o d dzisiaj) z p o la m i uporządkow anym i j a k o rok, # m iesiąc, dzień zam iast m iesiąc, dzień, rok.
select date(my date,
¡order
> [:year,
¡month,
:day])
# G eneruje znacznik s elec t daty ignorujący typ p o la # z w artością dom yślną b ę d ą c ą d atą z m y jd a te (sześć dni o d dzisiaj)
select datetime(my date time,
¡discard type
> true)
# G eneruje znacznik s elec t daty z w artością dom yślną b ę d ą c ą datą # z m y jd a te (sześć dni o d dzisiaj) p op rzed zon ą przedrostkiem „ p a y d a y ” # zam iast „ date ”.
select datetime(my date time,
192
|
Rails. Leksykon kie szo n ko w y
:prefix
> 'payday')
selectdatetime select_datetime(data_i_czas
Time.now,
opcje
{})
Zwraca zbiór znaczników select języka HTML (po jednym dla roku, miesiąca oraz dnia) wybranych za pomocą daty oraz czasu. Można w jawny sposób ustawić kolejność znaczników za pomocą opcji : order połączonej z tablicą symboli dla roku (: year), miesiąca (: month) oraz dnia (: day) w pożądanej kolejności. Jeśli żaden sym bol nie zostanie przekazany, zostanie on dodany na końcu przeka zanej opcji : order. Można również dodać klucze :date_separator oraz :time_separator w celu kontrolowania wizualnego formatu elementów. Przykłady my date time
Time.now + 4.days
# G eneruje znacznik s elec t daty i czasu z w artością dom yślną b ę d ą c ą # datą i czasem z m y jd a t e jim e (cztery dni o d dzisiaj).
select datetime(my date time) # G eneruje znacznik s elec t daty i czasu z w artością dom yślną rów ną dzisiaj # (bez ok reślon ej daty i czasu)
select date ti me () # G eneruje znacznik s elec t daty i czasu z w artością dom yślną b ę d ą c ą # datą i czasem z m y jd a t e jim e (cztery dni o d dzisiaj) z p o la m i # uporządkow anym i j a k o rok, m iesiąc, dzień zam iast m iesiąc, dzień, rok.
select datetime(my date time,
¡order
> [¡year,
¡month,
:day])
# G eneruje znacznik s elec t daty i czasu z w artością dom yślną b ę d ą c ą # datą i czasem z m y jd a t e jim e (cztery dni o d dzisiaj) z „ / ’’pom iędzy # każdym p o lem daty.
select datetime(my date time,
¡date separator
> '/')
# G eneruje znacznik s elec t daty i czasu ignorujący typ p o la # z w artością dom yślną b ę d ą c ą d atą z m y jd a te (cztery dni o d dzisiaj) .
select datetime(my date time,
¡discard type
> true)
# G eneruje znacznik s elec t daty i czasu z w artością dom yślną b ę d ą c ą # datą i czasem z m y jd a t e jim e (cztery dni o d dzisiaj), pop rzed zon ą #przedrostkiem „payday ” zam iast „ date ”.
select datetime(my date time,
:prefix
> 'payday')
M etody pom ocnicze
| 193
selectday select_day(data,
o p c je
{})
Zwraca znacznik select z opcjami dla każdego z dni od 1 do 31 z wybranym dniem dzisiejszym. Datę można również zastąpić liczbą godzin. Nazwę pola można nadpisać za pomocą opcji :f ield name; domyślnie ma ona wartość day. Przykłady my date
Time.today + 2.days
# G eneruje p o l e s elec t dla dni z w artością dom yślną dnia # z daty z m yjdate.
select day(my time) # G eneruje p o l e s elec t dla dni z w artością dom yślną rów ną #p o d a n e j liczbie.
select day(5) # G eneruje p o l e s elec t dla dni z w artością dom yślną dnia # z daty z m y jd a te o nazw ie „ due ” zam iast „ day ”.
select day(my time,
:field name
> 'due')
selecthour select_hour( d a t a _ i_ c z a s , o p c je
{})
Zwraca znacznik select z opcjami dla każdej z godzin od 0 do 23 z wybraną aktualną godziną. Godzinę można również zastąpić liczbą godzin. Nazwę pola można nadpisać za pomocą opcji : f ield name; domyślnie ma ona wartość hour. Przykłady my time
Time.now + S.hours
# G eneruje p o l e s elec t dla godzin z w artością dom yślną godzin # z czasu p o d a n e g o w m y jim e .
select hour(my time)
194
|
Rails. Leksykon kie szo n ko w y
# G eneruje p o l e selec t dla godzin z w artością dom yślną godzin # rów n ą p od an ej liczbie.
select hour(13) # G eneruje p o l e selec t dla godzin z w artością dom yślną godzin # z czasu p o d a n e g o w m y jim e o nazw ie „ stride ” zam iast „ hour ”.
select hour(my time,
¡field name
> 'stride')
selectm inute select_minute(data_i_czas, opcje
{})
Zwraca znacznik select z opcjami dla każdej z minut od 0 do 59 z wybraną aktualną minutą. Może również zwrócić znacznik s e le c t z opcjami o minute step od 0 do 59 z wybraną minutą 00. Minutę można również zastąpić liczbą minut. Nazwę pola można nadpisać za pomocą opcji : field name; domyślnie ma ona wartość minutę. Przykłady my time
Time.now + S.hours
# G eneruje p o l e selec t dla minut z w artością dom yślną minut # z czasu p o d a n e g o w m y jim e .
select minute(my time) # G eneruje p o l e selec t dla minut z w artością dom yślną minut # rów n ą p od an ej liczbie.
select minute(14) # G eneruje p o l e selec t dla minut z w artością dom yślną minut # z czasu p o d a n e g o w m y jim e o nazw ie „ s trid e ” zam iast „m inu tę”.
select minute(my time,
¡field name
> 'stride')
selectm onth select_month(data, opcje
{})
Zwraca znacznik select z opcjami dla każdego z miesięcy od stycznia (January) do grudnia (December) z wybranym aktualnym miesiącem.
M etody pom ocnicze
| 195
Przykłady # G eneruje p o l e selec t dla m iesięcy z w artością dom yślną rów ną # bieżącem u m iesiącow i, w ykorzystując klucze takie j a k „ Ja n u a r y ” # czy „ M arch ”.
select m o n t h ( D a t e .today) # G eneruje p o l e selec t dla m iesięcy z w artością dom yślną rów ną # bieżącem u m iesiącow i o nazw ie „ s ta r t” zam iast „m on th ”.
select m o n t h ( D a t e .t o d a y , :field name
> 'start')
# G eneruje p o l e selec t dla m iesięcy z w artością dom yślną rów ną # bieżącem u m iesiącow i, w ykorzystując klucze takie j a k „ 1 ”, „ 3 ”.
select
m o n t h ( D a t e .t o d a y , :use
month numbers
> true)
# G eneruje p o l e selec t dla m iesięcy z w artością dom yślną rów ną # bieżącem u m iesiącow i, wykorzystując klucze takie j a k „1 - Ja n u a r y ”, # „ 3 - M a rc h ”.
select
m o n t h ( D a t e .t o d a y , :add
month numbers
> true)
# G eneruje p o l e selec t dla m iesięcy z w artością dom yślną rów ną # bieżącem u m iesiącow i, w ykorzystując klucze takie j a k „ J a n ”, „ M a r”.
select
m o n t h ( D a t e .t o d a y , :use
short month
> true)
# G eneruje p o l e selec t dla m iesięcy z w artością dom yślną rów ną # bieżącem u m iesiącow i, w ykorzystując klucze takie j a k „ Ja n u a r ”, # „ Marts ”.
select m o n t h ( D a t e .t o d a y , :use ^F e b r u a r Marts . . .))
month names
>
%w(]anuar
selectsecond select_second(data_i_czas, opcje
{})
Zwraca znacznik select z opcjami dla każdej z sekund od 0 do 59 z wybraną aktualną sekundą. Sekundę można również zastąpić liczbą sekund. Nazwę pola można nadpisać za pomocą opcji :field name; domyślnie ma ona wartość second. Przykłady my time
Time.now + IS.minutes
# G eneruje p o l e s elec t dla seku n d z w artością dom yślną sekund # z czasu p o d a n e g o w m y jim e .
select second(my time)
196
|
Rails. Leksykon kie szo n ko w y
# G eneruje p o l e selec t dla seku n d z w artością dom yślną sekund # rów n ą p od an ej liczbie.
select second(33) # G eneruje p o l e selec t dla seku n d z w artością dom yślną sekund # z czasu p o d a n e g o w m y jim e o nazw ie „ in terval” zam iast „ s e c o n d ”.
select second(my time,
¡field name
> 'interval')
selectyear select_year(data, opcje
{})
Zwraca znacznik select z opcjami dla każdego z pięciu lat, licząc w obie strony od aktualnie wybranego roku. Przykłady # G eneruje p o l e selec t d la lat z w artością dom yślną rów ną # aktualnem u rokow i ze wzrastającym i w artościam i lat.
select year(Date.today,
¡start year
> 1992,
¡end year
> 2007)
# G eneruje p o l e selec t d la lat z w artością dom yślną rów ną # aktualnem u rokow i o nazw ie „ b irth ” zam iast „ y e a r ”.
select year(D a t e .t o d a y , ¡field name
> 'birth')
# G eneruje p o l e selec t d la lat z w a r to ś c ią dom yślną rów ną # aktualnem u rokow i z m alejącym i w artościam i lat.
select year(Date.today,
¡start year
> 2005,
¡end year
> 1900)
# G eneruje p o l e selec t d la lat z w artością dom yślną rów ną # rokow i 2008 ze w zrastającym i w artościam i lat.
select year(2008,
¡start year
> 2000,
¡end year
> 2010)
tim eselect time_select(nazwa_obiel
opcje
{})
Zwraca zbiór znaczników select języka HTML (po jednym dla godziny, minuty oraz opcjonalnie sekund) wybranych w celu uzyskania dostępu do określonego atrybutu czasu (identyfikowa nego przez metodę) dla obiektu przypisanego do szablonu (identy fikowanego przez obiekt). Sekundy można dołączyć za pomocą opcji :include seconds.
M etody pom ocnicze
| 197
Przykłady # G eneruje znacznik s elec t czasu, który p o zastosow aniu m etody PO ST # zostan ie przechow an y w atrybu cie sunrise zm iennej post.
time se le ct("post", "sunrise") # G eneruje znacznik s elec t czasu, który p o zastosow aniu m etody PO ST # zostan ie p rzechow an y w atrybucie subm itted zm iennej order.
time se lect("order", "submitted") # Tworzy znacznik s elec t czasu, który p o zastosow aniu m etody PO ST # zostan ie p rzechow an y w atrybu cie sent_at zm iennej mail.
time se le ct("mail", "sent at") # Tworzy znacznik s elec t czasu z p o lem sekund, który p o zastosow aniu # m etody PO ST zostan ie przechow an y w atrybucie sunrise zm iennej post.
time se le ct("post", "start time",
¡include seconds
> true)
# Tworzy znacznik s elec t czasu z p o lem sekund, który p o zastosow aniu # m etody PO ST zostan ie przechow an y w atrybucie subm issionJ i m e # zm iennej entry.
time select("entry", "submission time",
¡include seconds
> true)
# M ożna ustawić :m inute_step na 15, c o da nam 00, 15, 30 oraz 45.
time select
'game1, 'game time',
{¡minute step
> 15}
FormHelper Moduł FormHelper zaprojektowany został w celu uproszczenia pracy z modelami (w porównaniu z wykorzystywaniem standar dowych elementów języka HTML), dzięki udostępnieniu zbioru metod służących do tworzenia formularzy w oparciu o modele. Metody te służą do generowania kodu HTML formularzy i udo stępniania metody dla każdego rodzaju danych wejściowych (tek stu, hasła, pola wyboru). Moduł FormHelper udostępnia następujące metody pomocnicze:
checkbox c h e c k _ b o x ( nazwa_obiel
198
|
Rails. Leksykon kie szo n ko w y
"0")
Zwraca pole wyboru służące do dostępu do podanego atrybutu (identyfikowanego przez metodę) na obiekcie przypisanym do szablonu (identyfikowanym przez obiekt). Przykłady # Powiedzmy, ż e @ post. validated? m a w artość 1:
check boxC'post", "validated") # # # Powiedzmy, ż e @ p u ppy.gooddog m a w artość "no
Jeśli nie mamy obiektu, wystarczy podać nazwę parametru: <% fields for ¡person do (permission f i e l d s | %> Administrator?: <% permission fields.check box :admin %> <% end %>
file fie ld file_field(naziva_obie/
opcje
{})
Zwraca znacznik przesyłania pliku służący do dostępu do poda nego atrybutu (identyfikowanego przez metodę) na obiekcie przy pisanym do szablonu (identyfikowanym przez obiekt). Dodatkowe opcje znacznika input można przekazać jako tablicę asocjacyjną z opcjami. Opcje te zostaną wstawione do kodu HTML jako atry buty elementów HTML, jak w poniższych przykładach. Przykłady file f i e l d ( :u s e r , :avatar) # file field(:post, :attached, :accept > 'text/html') # file f i e l d (:attachment, ¡file, :class > 'file input') #
200 |
Rails. Leksykon kie szo n ko w y
form for foxm_foT(iekoid_lub_nazwa_tablicy, *a ig um en ty, &proc)
hiddenfield h i d d e n _ f i e l d ( nazwa_obiektu, metoda,
opcje
{})
Zwraca znacznik i n p u t typu h i d d e n służący do dostępu do poda nego atrybutu (identyfikowanego przez metodę) na obiekcie przy pisanym do szablonu (identyfikowanym przez obiekt). Przykład hidden field(:user, :token) #
M etody pom ocnicze
| 201
label la be l(nazwa_obiektu, metoda,
tekst
nil,
opcje
{})
Zwraca znacznik l a b e l służący do podpisania pola i n p u t dla okre ślonego atrybutu (identyfikowanego przez metodę) na obiekcie przypisanym do szablonu (identyfikowanym przez obiekt). Przykłady label(:post, :title) # label(:post, :title, "Krótki tytuł") #