Skocz do zawartości

Witaj na forum webmasterów Webax.pl.

Wyświetl nową zawartość

Ruby on Rails - alternatywa PHP - część piąta - rejestracja


  • Zaloguj się, aby dodać odpowiedź
Brak odpowiedzi do tego tematu
Soanvig
Soanvig

    Początkujący

  • Użytkownik
  • PipPipPip
  • 114 postów
#1

Napisano 29 sierpień 2012 - 20:53

Dzisiaj napiszemy pierwszą część systemu userów.
Przewidziałem w projekcie następujące akcje:
- utworzenie konta
- usunięcie konta
- zalogowanie
- wylogowanie
Dzisiaj zrealizujemy utworzenie konta, a może i trochę więcej :)

Uruchommy więc serwer na naszym projekcie tutorial i otwórzmy następujące pliki:
- ./config/routes.rb
- ./app/controllers/account_controller.rb
- ./app/models/user.rb
- ./viewer/account/start.html.erb
- ./viewer/account/new.html.erb



Osobiście w przypadku pisania projektów przyjmuję taką kolejność pisania akcji, w jakiej to kolejności pracuje użytkownik.

A więc zaczynamy. Najpierw zajmijmy się tym, czy użytkownik nie jest przypadkiem już zalogowany. Zapoznam was w ten sposób z systemem sesji w RoR. Otwórzmy zatem controller account_controller.
class AccountController < ApplicationControllerdef startenddef newenddef removeenddef loginenddef logoutendend
Widzimy klasę AccountController oraz < ApplicationController. Oznacza to, że AccountController ciągnie metody, zdarzenia itp. z głównego i nadrzędnego kontrolera ApplicationController. Poniżej mamy poszczególne metody, które zdefiniowaliśmy przy tworzeniu projektu. Zacznijmy od metody start, którą ustawiliśmy na stronę startową.

Proponuję następującą organizację:
- jeśli użytkownik jest zalogowany wyświetl mu start
- jeśli użytkownik nie jest zalogowany przekieruj go do kontrolera rejestracji new

W moim systemie, jeśli istnieje sesja dla aktualnego użytkownika oznacza to, że jest on zalogowany. Prosty system, ale lepszy nie jest potrzebny, ponieważ nie są potrzebne inne sesje. W RoR w przeciwieństwie do PHP nie trzeba się bawić w session_start();. W każdym miejscu skryptu możemy użyć po prostu zmiennej:
session[:user_id]
Proste, prawda? :) W :user_id znajduje się identyfikator użytkownika, który korzysta z naszego skryptu. W PHP jest to automatycznie dopisywane, ale w Rails mamy jak widać dowolność, czy chcemy, żeby sesja była indywidualna dla każdego użytkownika, czy globalna.

Tak więc spełnijmy warunek zalogowania i przekierowanie do rejestracji. Będziemy potrzebowali sesję i funkcję redirect_to. Funkcja ta wygląda następująco:
redirect_to :controller => "kontroler", :action => "metoda"redirect_to :action => "metoda"redirect_to "http://url"
W przykładzie pierwszym podajemy nazwę kontrolera i akcję, do której ma się przenieść wykonywanie skryptu.
W przykładzie drugim przenosimy interpreter do metody w kontrolerze, w którym aktualnie jesteśmy.
W przykładzie trzecim przenosimy użytkownika do zewnętrznego adresu URL.

Znając lub nie składnię Ruby - w celu skrócenia zapisu warunku możemy najpierw podać pojedyncze polecenie, a następnie w tej samej linijce, za poleceniem dopisać warunek. Nie musimy wtedy używać bloku if--end, ale nie możemy użyć else. W tym wypadku wbrew pozorom else nie będzie nam potrzebne. A to dlatego, że jeśli na początku sprawdzimy czy użytkownik nie jest zalogowany i go od razu przeniesiemy jeśli nie jest, viewer start i tak nam się nie pojawi, ponieważ przeszliśmy do innego miejsca w aplikacji. Natomiast jeśli warunek nie zostanie spełniony i interpreter dojdzie do końca metody, sam domyślnie wyświetli swój viewer (o tym już wspominałem). Wiedza o tym, jak działają Railsy pozwala znacząco upraszczać kod i z tego zdarzenia skorzystamy też później wielokrotnie. Tak więc zapiszmy odpowiedni w metodzie start:
def startredirect_to :action => "new" if !session[:user_id]end
I tyle! Teraz spróbujmy uruchomić naszą stronę i zobaczmy, do którego viewera nas przeniesie. Powinien to być viewer new w kontrolerze account.

Account#new

Find me in app/views/account/new.html.erb

Aha! Działa! :) W tym momencie, musimy dokładnie ten sam warunek na zalogowanie wrzucić do rejestracji (oczywiście tym razem trzeba sprawdzić czy user JEST zalogowany, inaczej wpadniemy w pętlę przekierowań - w takim wypadku Rails zablokuje skrypt i wyświetli stosowną informację). Przecież nie powinno być możliwości rejestracji, jeśli jesteśmy zalogowani. Spróbujcie więc sami dla metody new napisać warunek zalogowania przekierowywujący do metody start: ściagawka.

Okej, jeśli user nie jest zalogowany wyświetli mu się viewer, w którym powinien znajdować się formularz rejestracji. Otwórzmy viewer new.html.erb i utworzmy taki formularz za pomocą generatora formularzy Rails:
<h1>Register here!</h1><%= form_for "user", :url => { :action => "new" } do |f| %><%= f.label "username" %><%= f.text_field "username" %><%= f.label "password" %><%= f.password_field "password" %><%= f.label "email" %><%= f.text_field "email" %><%= f.submit %><% end %>
Za pomocą tegoż helpera budowania formularzy nie utworzymy pięknego w kodzie formularza, ale będzie wszystko przynajmniej działało :) Na razie nie przejmujmy się kodem HTML i CSS (dlatego też użyłem
).

W Rails znaczki <% %> interpretowane są tylko i wyłącznie we viewerach. Są to znaki otwierające i zamykające blok skryptowy. Jeśli dodatkowo po znaku otwierającym umieścimy znak równości: <%= będzie to informacja dla Railsów, że podany kod ma coś wyświelić. W tym przypadku form_for ma wyświetlić ramy formularza, a end tylko zakończyć wykonywanie tego bloku. Dlatego właśnie end nic nie wyświetla - form_for przy zakończeniu działania automatycznie wyświetli </form>.

Omówmy konstrukcję form_for.
Jako pierwszy argument musimy podać nazwę pomocniczą, wykorzystywaną przez Rails w różnych celach. W przypadku naszego kodu pojawi się ona jedynie na przycisku submit w formie: "Save User" oraz w nazwie formularza. Formularz nazywamy, poprzez nadanie name dla wszystkich inputów w następującej formie: nazwa_formularza[nazwa_pola]. Jeśli jej nie podamy, Rails zwróci błąd.
Jako drugi argument podajemy adres, do którego ma zostać wysłany formularz. Należy go podać do :url =>. Możemy podać ręcznie adres url zamykając go w cudzysłowach, lub wykorzystać do tego celu Railsy i podać akcję, która się wykona. I w ten oto sposób:

:url => { :action => "new" } ---> <form action="/account/new">
:url => "/account/new" ---> <form action="/account/new">
:url => "http://google.pl"���...e.pl"����--->�� <form action="http://google.pl">

W tym generatorze domyślnie wykorzystywana jest metoda POST.

Pole <textarea> możemy wyświetlić za pomocą f.text_area. A właśnie! To "f" pochodzi z bloku form_for - jest to zmienna tymczasowa, taka sama jak przy funkcji foreach w PHP.
Cała reszta w tym kodzie wydaje się być logiczna. Jeśli ktoś ma pytania proszę je zadać poniżej.

Formularz mamy napisany. Teraz trzeba dodać routing dla danych POST, które docelowo mają trafić do account/new (action formularza) i zezwolić na przekazywanie ich do account#new. Otwórzmy plik routes.rb i dodajmy następującą linijkę:
post "account/new" => "account#new"
Spróbujmy w takim razie teraz zapisać te dane do bazy. Otwórzmy więc znowu kontroler account i wróćmy do metody new:
def newredirect_to :action => "start" if session[:user_id]end
Na razie mamy tylko przekierowanie, jeśli użytkownik jest zalogowany. Natomiast trzeba coś zrobić z formularzem. Wszystkie parametry z formularzy przekazywane są w zmiennej params["nazwa formularza"]. Więc teraz logika skryptu może wyglądać następująco:
- jeśli zalogowany - przekieruj do startu
- jeśli przesłano parametry - zapisz je w bazie
- jeśli żadne z powyższych - wyświetl viewer (formularz)

Pierwszy punkt mamy spełniony. Trzeci mamy z automatu. Zajmijmy się drugim - sprawdźmy, czy wysłano jakieś parametry z formularza o nazwie "user". Zbudujcie więc na razie sam blok i umieście go za przekierowaniem: ściągawka.
Teraz w bloku umieścimy zapis tych danych w bazie danych.
data = {"username" => params["user"]["username"],"password" => params["user"]["password"],"email" => params["user"]["email"],"register_date" => DateTime.now.to_date}@save = User.new(data)@save.save
Do zmiennej @save, która jest zmienną klasową, przypisujemy obiekt modelu User z danymi w formie tablicy, gdzie klucze oznaczają nazwy pól w tabeli, a wartości - dane, które mają zostać do odpowiednich pól przypisane. Następnie dane te zapisujemy do bazy. Proste, prawda? Dużo prostsze niż w PHP? To już pozostawiam waszej ocenie.

Metoda .save dla modelu zwraca true lub false - wykorzystamy to przy budowaniu systemu walidacji danych.
Na koniec możemy jeszcze po zapisaniu danych zrobić przekierowanie do strony startowej, ale jako, że i tak nas przekieruje do formularza rejestracji - na razie jest to kompletnie bez sensu.

Generalnie wszystko co powyżej napisałem pisałem "z palca" i nie sprawdzałem, czy będzie poprawnie dopisywać do bazy, ale... powinno :D Czy działa - przekonamy się w następnej części.

W następnej części zajmiemy się walidacją danych pochodzących z formularza, wyświetlaniem błędów i może logowaniem, wylogowywaniem oraz usuwaniem konta.

@Thelleo, jak chcesz to punktuj http://webax.pl/publ...tyle_emoticons/default/xd.gif

EDIT:
Wprowadziłem drobne poprawki związane z wyjaśnieniem routingu POST oraz nazwą formularza.
  • 1

[font="Courier;"].oooooooo8....ooooooo......o......oooo...oooo.888.........o888...888o...888......8888o..88...888oooooo..888.....888..8..88.....88.888o88..........888.888o...o888.8oooo88....88...8888..o88oooo888....88ooo88.o88o..o888o.o88o....88..[/font]