04 marca 2009

Wystąpienia publiczne jako utrwalenie wiedzy z Grails w tle

Podczas wczorajszej prezentacji Grails na 42. spotkaniu Warszawa JUG popełniłem jeden błąd, któremu już więcej się nie dam - mam rozwiązanie i to z pomocą osoby z sali. Jest to jeden z powodów, dla którego warto wystawić się na publiczną krytykę. Przed prezentacją miałem wiele obaw, czy jestem odpowiednio przygotowany do jej poprowadzenia, ale teraz po niecałych 2h wystąpienia czuję się znacznie mocniejszy i występ na 4Developers będzie jak bułka z masłem. Podczas spotkania miałem prawie 120 minut, a 4Developers to jedynie 60 minut, więc jedynie (?) to będzie wyzwaniem - sam Grails już nie powinien. Przynajmniej nie w zakresie, który przedstawię.

Zacząłem prezentację Grails od omówienia jego składowych - klasy dziedzinowe, kontrolery, strony GSP i wzmianką o klasach usługowych, pomocniczych i znacznikach GSP. Na poparcie moich słów postanowiłem zaprezentować przykładową aplikację bez użycia IDE, jedynie z użyciem polecenia grails.

Najpierw grails help dla rozruszania publiczności czymś działającym. Później grails create-app nauczyciel, a następnie grails create-domain-class pojecie i grails create-controller pojecie. Miałem pustą klasę dziedzinową oraz domyślny kontroler, który wyglądał tak:
 class PojecieController {
def index = { }
}
Sądząc, że mam wszystko podszedłem do uruchomienia aplikacji z grails run-app.
 $ grails run-app
Welcome to Grails 1.1-RC2 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: c:/apps/grails

Base Directory: C:\projs\sandbox\nauczyciel
Running script c:\apps\grails\scripts\RunApp.groovy
Environment set to development
...
Running Grails application..
Server running. Browse to http://localhost:8080/nauczyciel
Otwieram przeglądarkę pod adresem http://localhost:8080/nauczyciel, wybieram jedyny dostępny kontroler PojecieController i...bum!

Trochę mnie to wprawiło w zakłopotanie, szczególnie, że to dopiero początek moich programistycznych wyczynów z Grails podczas prezentacji (!) Wcześniej, jakimś cudem, nie przytrafiło mi się to. Na sali było około 50 osób i na moje pytanie o jakiekolwiek (nawet minimalne - samo czytanie o nim) doświadczenia z Grails rękę podniosła wyłącznie jedna osoba (nie czytają mojego bloga?!). Byłem w tarapatach.

Sądząc, że to brak *czegoś* zabrałem się za podobną aplikację z użyciem NetBeans 6.7. Nie trwało długo zanim okazało się, że nie jest lepiej - znowu 404. Chwila zadumy (a wszyscy z sali patrzą) i mam rozwiązanie! Wszystko za sprawą cudownej zasady konwencja-zamiast-konfiguracji (ang. CoC - Convention over Configuration).

I teraz pytanie do czytelników: Dlaczego otrzymałem błąd 404? Jako podpowiedź napiszę, że wszystkie dane do rozwiązania problemu są w tym wpisie. Trochę logicznego myślenia i znalezienie rozwiązania stanie się banalne (poodbnie jak te dowody twierdzeń z wykładów analizy matematycznej ;-)).

10 komentarzy:

  1. Jacku to jeszcze jeden tip od publiczności z sali. Elvis to skrócony ternariusz (ang. ternary operator) a oparator, który pokazywałeś czyli *. to spread operator.

    OdpowiedzUsuń
  2. Łukasz, Grzegorz strzelajcie dalej. Jackowi chodzi o to dlaczego w ogóle Grails szuka pliku widoku? Powinien przecież zadziałać scaffolding.

    OdpowiedzUsuń
  3. Teraz to jasne, chodzi oto co poniżej?

    class PojecieController {
    def scaffold = Pojecie

    def index = { }

    }

    OdpowiedzUsuń
  4. Tjaaa, z pomoca kogos z sali, przez przypadek tym ktosiem bylem ja :) Btw. Gdybys zajrzal do mnie na bloga wczoraj to zobaczylbys dokladnie to samo co probowales stworzyc na prezentacji.

    OdpowiedzUsuń
  5. grails generate-view Pojecie :)

    Dlatego ja zwykle modeluję ile jestem w stanie Encję, a potem robie grails generate-all Encja. W ten sposób się nie zapomni :)

    OdpowiedzUsuń
  6. Jeszcze jedno w sumie - pewnie wiesz, ale jak użyjesz generate-controller zamiast create-controller to troszeczkę więcej jest w tym kontrolerze niż tylko index ;)

    OdpowiedzUsuń
  7. Aby scaffolding działał model musi posiadać przynajmniej jeden atrybut.

    OdpowiedzUsuń