Validacja formularza przy innych akcjach

Próbuje sparwdzić poprawność formularza za pomocą validates_*_of. Jednak formularz nie kieruje na żadną standartoewą akcje, tylko na order_save, przez co testy nie są uruchamiane.

Próbowałem sie bawić : on => ‘order_save’, i z :if jednak to nie podziałało.

Jak mogę przeprowadzić walidację niestandartowego formularza?

Update:
W zasadzie to mam taki sam problem jak tutaj:
http://forum.rubyonrails.pl/viewtopic.php?id=45
jednak z tego co czytam, to kod będą cy rozwiązaniem gdiześ zaginął :frowning:

Pamietaj, ze nie sprawdzasz poprawnosci formularza a poprawnosc obiektu (Modelu). Dane z formularza tylko spinasz z tym obiektem, rownie dobrze moga pochodzic z jakiegokolwiek innego zrodla.
Otworz sobie konsole, stworz obiekt danego modelu i
Zakldajac, ze masz klase modelu o nazwie Issue:

./script/console test_issue = Issue.new test_issue.save! # tu powinien wyrzucic bledy walidacji danych

No i oczywiscie :on przyjmuje wartosci :save :create :update prawda ?
Jak rozumiem chcesz stworzyc swoj wlasny save prawda ? od tego masz

after_save :metoda, :metoda2, :metoda3 itd

lub

def after_save [..]kod twojej metody[..] end
tak samo w przypadku before_* Oczywiscie tutaj wskazane by bylo chyba before prawda ? :slight_smile: bo chcesz wykonac o przed validacja, after jest juz po :slight_smile:

Ogólnie i dokładnie to mam zadanie, by zrealizować zamawianie towarów ze sklepu internetowego. W PHP bym zrobił coś takiego bez problemu, ale że próbuje sie pouczyć Rubiego od jakiegoś miesiąca, to postanowiłem to zrobić w railsach.

Zrobiłem sobie w scaffoldzie model Product. W list dodałem formularz, który do listy produktów dodaje pole tekstowe, w które mogę wpisać iler sztuk danego produktu chcę kupić. Potem ten formularz prowadzi do ‘order’, które sparwdza poprawnośc wprowadzonych danych i jeśli sa poprawne, to przekierowuje na order_save, którego zadnaiem jest jedynie wyświetlić komunikat, że zamówienie zostało przyjęte.

Wiem, że mógłbym stworzyć kolejną tebelę SQL orders i kolejny model i w nim obsługiwac zamównienia (a nawet tak powinienem pisząc cały sklep :slight_smile: ), ale chciałem przy okazji sie nauczyć co robić by kontrolować własne formularze.

Kod, który wymysliłem jest raczej strasznym potworem i pewnie przeczy wszystkim zasadom pisania w railsach, ale działa :slight_smile:

[code=Ruby] def order
@cena = 0;
@products = Array.new
@params[:order].each { |id, amount|
product = Product.find(id)
if amount.to_i > product.amount or not amount =~ /^\d*$/
flash[:notice] = “Zamówiłeś za duzo sztuk “+product.name+”, badź podałeś nieprawidłową liczbę”
redirect_to :back
else
@products.push( Hash[‘name’ => product.name, ‘cena’ => product.price, ‘sztuk’ => amount, ‘id’ => id ] )
@cena += product.price*amount.to_i
end
}
if not @params[:product].nil?
flash[:notice] = “”
if @params[:product][:imie].length < 2
flash[:notice] << “Podaj imie!

end
if @params[:product][:nazwisko].length < 3
flash[:notice] << “Podaj nazwisko!

end
if @params[:product][:adres].length < 10
flash[:notice] << “Podaj adres!

end
if flash[:notice].length == 0
redirect_to :action => ‘order_save’
end
end

end[/code]

if not @params[:product].nil? == unless params[:product] (niedługo @params bedzie deprecated:)
if flash[:notice].length == 0 == unless flash[:notice]
co do reszty… to o matko boska :wink: widac ze przezyles ciezka szkole php, gdzie zapisujesz te dane ? nie widze nigdzie save :slight_smile: skoro sa walidacje dla modelu to lepiej ich uzywac, nikt nie zmusza ale po co wymyslac kolo od nowa ? wystarczy ze stworzysz tabele orders, model order z tymi walidacjami w tym przypadku validates_presence_of najczesciej i wszystko przeniesiesz z @params[:product] do @params[:order] a prznajmniej wszystko to co powinno byc w zamówieniu a czego byc nie powinno w produkcie, a wtedy juz wystarczy tylko @order = Order.new(@params[:order]).save_with_validation :wink: Oczywiscie uzywam duzych skrotow myslowych…

Nie traktuj Rails jak php :slight_smile: Nie wymyslaj wszystkiego od nowa, sprawdz dokumentacje, scaffold, przeczytaj agile development with rails traktuj to jako nowy jezyk ktory ci ma ulatwic zycie a nie utrudnic, tak sobie je tylko utrudniasz

[quote=PaK]if not @params[:product].nil? == unless params[:product] (niedługo @params bedzie deprecated:)
if flash[:notice].length == 0 == unless flash[:notice][/quote]
Dobrze wiedzieć :slight_smile:

No, z php mam juz jakies 5-6 lat doczynienia :slight_smile:
Natomiast tak, jak opisałeś, to wiem że taki jest najbaridzej prawidłowy sposób na zrobienie powyższego przykładu. Ale chciałem się nauczyć czegoś nowego :slight_smile:

Inny przykład:
Jak przeprowadzić walidację formularza kontaktowego? Wiadomości nie będzie się zapisywało w bazie, tylko wysyłało na podany adres admina.

Staram się - cały czas jak tylko mam czas to dizelnie dizalam :slight_smile:

Teoretycznie mozesz to zrobic tworzac zwykly model Activerecord z walidacjami a potem juz tylko:

@contact = Contanct.new(params[:contact]) if @contanct.valid? Uzycj ActiveMail tutaj else render :action => "contanct" end
Teoretycznie powinno dzialac ale tylko z validacjami ktore nie odwoluja sie do bazy danych, np uniques juz zwrocil blad ze tablica nie istnieje w bazie danych :wink: Sprawdz

Śmiem twierdzić, że trochę bez sensu jest uczenie się “czegoś nowego” w przypadku gdy owo “nowe” jest kompletnie nieprzydatne i na pewno nie w stylu rails’ów :wink:
Przypomniało mi się jak pisałem pierwszą aplikację w railsach (blog z dużą ilością ajax’a) zaraz po przeczytaniu pierwszego tutoriala. Na początku ustawiłem sobie ładnie w modelach has_many i belongs_to, po czym pobierałem dane z bazy w oddzielnych zapytaniach. Bez sensu :wink:

Czyli tak:

@post = Posts.find(…)
@comments = Comments.find(…)

? Ja robiłem dokładnie to samo :slight_smile:

Dokładnie. :slight_smile:

cyrylas: jeszcze jedna rada. Jak chcesz cokolwiek zrobić w railsach dokładnie przejrzyj api railsów i rubiego. Kiedyś jak powiedziałem, że chcę zostać czarodziejem railsowym kumpel stwierdził: railsy są przecież banalne, na 2 tygodnie nauki. A prawda jest taka, że owszem, railsy są bardzo proste, ale trzeba wiedzieć jakie mamy możliwości, żeby je wykorzystać. Bez tej wiedzy będziemy pisać rzeczy, które już są napisane, wyważać już otwarte drzwi. Nie mówiąc już o możliwościach rubiego - dużo doświadczenia potrzeba, żeby naprawdę móc powiedzieć: mój kod jest napisany “in ruby-way” :wink:

[quote=PaK]Teoretycznie mozesz to zrobic tworzac zwykly model Activerecord z walidacjami a potem juz tylko:

@contact = Contanct.new(params[:contact]) if @contanct.valid? Uzycj ActiveMail tutaj else render :action => "contanct" end
Teoretycznie powinno dzialac ale tylko z validacjami ktore nie odwoluja sie do bazy danych, np uniques juz zwrocil blad ze tablica nie istnieje w bazie danych :wink: Sprawdz[/quote]
Sprawdziłem i teoria zawiodła :confused:

Model sobie testowy zrobiłem nic szczególnego:

class Contact < ActiveRecord::Base validates_format_of :mail, :with => /^[a-zA-Z][\w\d]*\@[\w\d\.]+\.[a-zA-Z]{2,4}$/ validates_length_of :msg, :minimum => 2 end
Czyżby każdy model musiał mieć odpowiadającą sobie tabelę?

Wiesz co moj pomysl byl ciekawy ale to sie nie sprawdzi :wink: bo przeciez ActiveRecord chyba potrzebuje nazw pol z tabeli zeby wiedziec co ma konkretnie validowac, ale sprawdz czy set_table_name w modelu cos by pomoglo ustaw tabele na jakas ktora istnieje w bazie :slight_smile:

Pobawiłem się set_table_name i nic. Przetrzepałem manuala, by zobaczyć czy da sie zdefiniowac jakaś wirtulną tabelę i ręcznie podać kolumny, ale railsy nic takiego nie przewidują.

Chyba odkryłem poważny minus railsów :). Model może operować jedynie na instniejącej tabeli. Także za kązdym razem odczytuje sobie te kolumny z mysql, czyli teorycznie robi co najmniej jedno niepotrzebne zapytanie i w ten sposób marnuje czas :slight_smile:

Robi to tylko gdy pracujesz w trybie development. W production nic takiego się nie dzieje, rozkład kolumn jest keszowany.

Do obiektowego modelowania i walidacji formularzy służy plugin active-form.

No to jak jednak Rails nie za każdym razem czyta dafinicje kolumn, to jednak nie jest zły :slight_smile:

A to active form to przetestuję następnym razem, bo ten sklep, nad którym siedziałem tyle czasu, to w końcu napisałem w php w godzinę :slight_smile:

Na chwilę obecną cyryl vs Rails 0 : 1, ale sie nie poddaję :slight_smile:

GIT :slight_smile: przyda sie napewno :slight_smile: Zwlaszcza ze wszystko dziala z wykorzystaniem:

public include ActiveRecord::Validations include ActiveRecord::Callbacks