link_to_remote a walidacja w modelu

Witam,

uzywam sobie wstawek ajaxowych poprzez link_to_remote - kiedy wchodze na strone glowna mojej aplikacji mam tam menu oraz
DIV o nazwi ‘main’, ktory to ulega updetowi… kiedy wciskam link by przeniesc sie na strone do rejestracji wyswietlaja mi sie wszysytkie
mozliwe bledy walidacji (validates_uniqueness_of oraz validates_presence_of) tak jak bym wlasnie wcisnol submit… O to moj widok:

<% @page_title = “Add a User” -%>

<%= error_messages_for 'user' %>
<%= form_tag( :action => "add_user" ) %>
User name: <%= text_field("user", "name") %>
User Login: <%= text_field("user", "login") %>
Password: <%= password_field("user", "password") %>

<%= end_form_tag %>
oraz link jakiego uzywam zeby go sobie wyswietlic:

  • <%= link_to_remote( "Account Options", :update => "main", :loading => "loading( )", #metody JS do pokazywania i ukrywania :complete => "loaded( )", #paska postepu ... z animowanym gifem :url =>{ :controller => "login" }) %>
  • Jeżeli pojawiają ci się takie błędy w miejscu <%= error_messages_for ‘user’ %> to znaczy, że zmienna @user (lub user) zawiera obiekt klasy User, który ma niepustą tablicę @errors. Wniosek z tego taki, że gdzieś po drodze próbujesz zapisać nowoutworzony obiekt klasy User - poszukaj w kontrolerze słowa “save” :stuck_out_tongue: Dopóki nie próbujesz zachować obiektu do bazy, ActiveRecord nie przeprowadza sprawdzania i nie wypełnia tablicy @errors. Możliwe też, że error_messages_for wariuje, bo nie definiujesz zmiennej @user.

    PS. Jeżeli wszystkie pola formularza odnoszą się do usera, ja użyłbym <% form_for :user %>…<% end %>, w ten sposób oszczędzasz trochę pisania i zyskujesz trochę elegancji.

    Hej, dzieki za opowiedz… juz po trochu zaczynalem tracic nadzieje ze ktos mi poda jakas wskazowke …

    Przyjrzalem sie mojemu kontrolerowi… metoda add_user jest zywcem z “Agile Web Dev…” zastanawiam sie czy uzycie AJAXa moze byc problemem:

    Prosze o to ona… zastanawiam sie czy ten if jest zly? Czy ew. powinienem odwolac sie do np pustej metody iwidok tez nazwac inaczej a dopiero pozniej w tym widoku formularz powiniene odwolywac sie do ponizszej akcji.

    def add_user
    if request.get?
    @user = User.new
    else
    @user = User.new(params[:user])
    if @user.save
    redirect_to_index(“User #{@user.name} created”)
    end
    end
    end

    Dzieki z gory za odpowiedz.

    Pozdrawiam
    Lukasz

    Ten kod, który wkleiłeś jest OK (ja tylko dopisałbym jawne wywołanie “render” bez parametrów w części get, żeby było czytelniej). Z tego co zrozumiałem z Twojego pierwszego posta, to żądanie strony rejestracji wysyłasz poprzez AJAX (i nadesłaną stroną zastępujesz dotychczasowe “main”). Jeżeli dobrze zrozumiałem, to wszystko by się zgadzało - takie wywołanie to nie jest zwykłe GET, musisz zmienić “request.get?” na “request.xhr?” i wtedy powinno być OK (XHR = XML HTTP Request, czyli pierwotna nazwa AJAX’a)

    Swoją drogą, to żeby uniknąć w przyszłości podobnych niespodzianek dokładnie precyzuj, że formularz obsługujesz w przypadku żądania POST, a renderujesz go dla GET czy XHR (unikaj niejednoznaczynych “else”).

    Pozdrawiam,

    Benol

    Hej, dzieki

    Zastanawiam sie nadczyms jeszcze … gdy wciskam sobie linka login w moim div-ie “main” pojawia sie widok login.rhtml jego zatwierdzenie przenosi mnie spowrotem do glownego layoutu (wszystko na link_to_remote i redirect_to) ale zastanawia mnie cos innego: jesli logowanie sie nie powiedzie z jakiej kolwiek przyczyny… wyswietla mi sie sam widok login.rhtml bez layoutu + bledy etc… (layout mam w jednym widoku i w jego divie main wyswietlam wszystkie inne…) zastanawiam sie jak zrobic ze powrot z jednego kontorlera automatycznie odswiezy mi (wykona sie) w divie main innego widoku - czy jest to wogole mozliwe ? Czy zmuszony jestem kombinowac z partial layoutami ?

    Dziekuje za odpowiedz i pozdrawiam
    Lukasz

    nie wiem czy to Ci się przyda, ale zobacz na validacje taką:

    http://shnoo.gr/articles/2005/12/20/ajax-the-great

    nie wiem czy dobrze rozumiem Twój problem

    pozdrawiam

    Hej Punkracy - dzieki za odpowiedz… nie jest to jednak do konca to co mialem na mysli…
    Przepraszam za moj jezyk :stuck_out_tongue: jest za malo konkretny…

    Jeszcze raz o to sytuacja ktora mam:

    posiadam sobie jakis tam layout dla calej aplikacji. Do tego posiadam main_controller - ktory to ma widok main w tym widoku mam dwa div-y Jeden Menu oraz drugi wrapper.

    Div menu zawiera kilka link_to_remote do roznych rzeczy np logowania, wyswietlanie roznych rzeczy itd itp. Kiedy go sobie klikam wyswietla mi sie
    w Divie wrapper ta konkretna rzecz ktora chce np okienko z text-fieldami login i password. Okienko to jest widokiem kontrolera login_controller i nazywa sie login.rhtml

    Teraz gdy robie login dla user/passwd i logowanie sie udaje przekierowuje sie do main widoku i jest slicznie
    mam to samo co przed kliknieciem + jestem zalogowany.
    O to metoda controllera login:

    def login
    if request.get?
    session[:user_id] = nil
    @user = User.new
    else
    @user = User.new(params[:user])
    logged_in_user = @user.try_to_login
    if logged_in_user
    session[:user_id] = logged_in_user.id
    redirect_to(:controller => “start” ) ####!!! TUTAJ JEST POWROT DO GLOWNEGO
    else
    # flash[:err] = “Invalid user/password combination”
    # render(:controller => “login”, :action => “login” ) ###!!! JESLI TO SIE STANIE TO WYSWIETLI MI SIE SAM LOGIN.rhtml sam a nie caly main.rhtml z login.rhtml-em w wrapper divie jak powinno byc
    end
    end
    end

    Ufff mam szczera nadzieje ze jest to teraz bardziej zrozumiale :slight_smile: - wlasnie po nie udanym logowaniu chciabym zeby moj login.rhtml wraz z moim flashem wyswietlil sie ponownie w srodku wrapper diva…

    Dzieki z gory za odpowiedz
    Pozdrawiam
    Lukasz

    [quote=luki3k5]# flash[:err] = “Invalid user/password combination”
    # render(:controller => “login”, :action => “login” ) ###!!! JESLI TO SIE STANIE TO WYSWIETLI MI SIE SAM LOGIN.rhtml sam a nie caly main.rhtml z login.rhtml-em w wrapper divie jak powinno byc[/quote]
    może tak że w else dajesz
    render :action => “do_sth_with_errors”

    no i dajesz odpowiedni rjs template
    app/view/…/do_sth_with_errors.rjs
    a w nim:

    page.replace_html “wrapper”, :partial => “login”

    pod warunkiem ze masz takiego partiala _login.rhtml

    page to obiekt dostarczony templatowi i reprezentuje tą stronę z zapytania.

    hmm, sam nie wiem czy to zadziała :slight_smile: spróbuj

    pozdrowienia

    ps. rozumiem, że mówisz o login_controller jako o login_controller.rb a nie o LoginController ?
    pamiętaj o konwencjach nazewniczych (nie żebym się czepiał) ;p

    Hejka dzieki za naprowadzenie mnie na RJS - najwyrazniej jest to to czego potrzebuje :slight_smile:

    Zastanawiam sie czy mogl bys polecic mi jakis tutor z sieci do RJS - po googlowalem troszke ale wiekszosc z nich jest zdjeta z sieci :((( te co znalazlem opisuja bardziej wyrafinowane przypadki i zakladaly ze juz znam podstawy

    Z gory dzieki

    Pozdrawiam
    Lukasz

    Całkiem dobre wyjaśnienie do RJS znajdziesz tutaj

    Hej,

    Dzieki wszystkim. Udalo mi sie uzyskac to co chcialem o to sposob na wypadek gdyby ktos szukal:

    Mam widok login.rhtml ktory zawiera AJAXowy formularz:
    <%= form_remote_tag :url => { :action => “perform_login” } %>

    nastepnie w kontrolerze dla tego widoku mam:
    def perform_login
    if request.get?
    session[:user_id] = nil
    @user = User.new
    else
    @user = User.new(params[:user])
    logged_in_user = @user.try_to_login
    if logged_in_user
    session[:user_id] = logged_in_user.id
    session[:user_name] = logged_in_user.name
    @saved = true
    else
    @saved = false
    flash[:err] = “Invalid user/password combination”
    render :action => “perform_login”
    end
    end
    end

    i dzieki temu podczas nie udanego logowania zostaje ustawiona wiadomosc flash i calosc zostaje przekazana do widoku perform_login.rjs :

    if @saved == false #jesli sie nie uda
    page.replace_html ‘main’, :partial => “login”
    page.visual_effect :shake, ‘main’
    else # jesli sie uda
    page.replace_html ‘main’, “Logged in…”
    page.replace_html ‘logged’, :partial => “loggedin”
    page.visual_effect :Highlight, ‘main’
    end

    jak widac w zaleznosci czy sie powiodlo logowanie czy nie generuje text ze jestem zalogowany lub jeszcze raz widok login.rhtml z poczatku wraz z wiadomoscia flash.

    Pozdrawiam i dziekuje wszystkim za pomoc
    Lukasz