Problem z devise i redirectem po nieudanej rejestracji

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 :slight_smile:

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ę :).

  1. Wchodzę na /users/sign_up - odpala mi się akcja new z kontrolera devise/registrations.
  2. Klikam submit, przeglądarka wysyła POST z danymi z formularza na /users.
  3. Railsy dostaja ten POST reuquest i odpalaja akcje create z devise/registrations
  4. Akcja create próbuje zapisać usera, ale są błędy więc renderuje widok new z devise/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 :wink: 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 :slight_smile: