Mam taki problem. Wchodzę na /users/sign_up
, zostawiam wszystkie pola puste, klikam Sign up
i przenosi mnie na /users
z wyświetlonym formualrzem rejestracji i błędami. Co ciekawe nie mam w routesach ustawionego GET /users
, nie mam nawet kontrolera users z akcją index. Wiecie może o co chodzi i jak zrobić, żeby re-renderowało mi ten view spod /users/sign_up
? (aplikacj na Rails 4)
Railsowy pattern.
Jak model nie przejdzie walidacji, nie ma redirecta, tylko akcja create (update) renderuje widok new (edit).
Tak wiem o tym, ale to wszystko jest generowane przez devise, kontroler i widoki sa devisowe, dlatego pytam o co tutaj chodzi
masz engine devisa, który załatwia Ci routing i te akcje, o które pytasz, w typowo railsowy sposób.
Jeśli chcesz renderować swoje widoki to musisz je skopiować z Devise i zmienić:
Wszystko jest tutaj:
Widoki też mam skopiowane i pozmieniane. W sumie to wygląda tak jakby wsyzstko działało, jedyny problem, jest taki, że url jest zły(zamiast /users/sign_up pokazuje /users mimo, że jak wejdę bezpośrendio na /users to pokazuje błąd, bo nie mam ani kontrolera users ani tym bardziej indexa dla niego).
W kilku miejscach znalazłem identyczny problem (np. tutaj https://groups.google.com/forum/#!topic/plataformatec-devise/O6SKsVWzVTA), ale nie bardzo kapuje, jak nie mam nigdzie w routes zdefiniowane GET users
to jak mi może przeglądarka pokazywać formularz rejestracji pod tym adresem?
Według REST GET users/new powinno renderować formularz rejestracji, który jest wysyłany metodą POST na adres /users.
Natomiast GET users/ powinno zwrócić listę użytkowników. Devise natomiast nie implementuję tej metody, gdyż jest ona poza zakresem funkcjonalności gema.
Każdy użytkownik po wysłaniu formularza z błędami zostanie przekierowany na adres POST users/ jednak po odswieżeniu strony zostanie poproszony przez przeglądarke o ponowne przesłanie formularza. Jedynym obejściem, jest ręczne przejście pod adres users/ lub kliknięcie w pasku adresu i przejście ponowne pod ten sam adres.
Jeśli chcesz chcesz obejść brak adresu GET users/ to powinieneś dodać przekierowanie na adres GET users/sign_up
Ok, tutaj jest źródło create
w Devise:
def create
build_resource(sign_up_params)
if resource.save
if resource.active_for_authentication?
set_flash_message :notice, :signed_up if is_navigational_format?
sign_up(resource_name, resource)
respond_with resource, :location => after_sign_up_path_for(resource)
else
set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format?
expire_session_data_after_sign_in!
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
end
else
clean_up_passwords resource
respond_with resource
end
end
Interesuje mnie to ostatnie respond_with resource
, z tego co poczytałem, jeżeli jest wywoływane w create i resource ma jakieś błędy, to powinno działać tak samo jak render 'new'
.
Nigdzie tu nie widzę, jak może mnie przenosić na /users
, jakaś magia :/.
Ta akcja jest już wywołana po wysłaniu formularza i przejściu po adres /users.
respond_with jedynie spowoduję wykonanie akcji new (bez żadnego przekierowania) lub przekieruje pod ścieżke wskazaną w parametrze location jeśli zasób jest poprawny.
A więc formularz jest metodą POST na /users, tutaj zostaję wykonane akcja #create, który wykonuje akcję new, ponieważ zasób jest niepoprawny. Przeglądarka natomiast zostają na adresie /users, którego odswieżenie spowoduje ponowne przesłanie formularza
Ok, niby wszystko kapuję :).
- Wchodzę na
/users/sign_up
- odpala mi się akcjanew
z kontroleradevise/registrations
. - Klikam submit, przeglądarka wysyła
POST
z danymi z formularza na/users
. - Railsy dostaja ten
POST
reuquest i odpalaja akcjecreate
zdevise/registrations
- Akcja
create
próbuje zapisać usera, ale są błędy więc renderuje widoknew
zdevise/registrations
.
Chyba gdzieś w punkcie drugim się gubię. Czy to znaczy, że po kliknięciu w Submit
w adresie pojawia się /users
dlatego, że formularz leci na ten adres ? (myślałem, że jak jest POST to w przeglądarce adres się nie zmieni).
Czyli, żeby w przeglądarce było /users/sign_up po kliknięciu Submit, ten POST powinien iść na /users/sign_up zamiast /users więc powinienem ustawić routes, tak, żeby POST /users/sign_up kierował na create z devise’a?
Zgadza się.
Jest to jakieś rozwiązanie Zauważ, że tak właśnie działa akcja sign_in w devise. GET /users/sign_in renderuje formularz logowania, który jest kierowany na POST /users/sign_in.
Ok, możliwe, że jak się robi jakieś railsowe scaffoldy, to generuje to wszystko tak, że i get i post dla new i create lecą na ten sam adres (pewnie i tak zazwyczaj się tak robi) i stąd moje zdziwienie :). Jeżeli tak rzeczywiście jest, to chyba mogę to uznać za WOW moment