Model, validacja, xhr on => :create | problemo uno :)

Witam.

Napisałem sobie w modelu powiedzmy coś takiego:

validates_uniqueness_of :nip, :regon, :on => :create

Teraz wywołuję całą validację modelu przez ajaxa (jquery, określając czy metodą post czy put)
W logu mam dokładnie pokazane że wywołanie jest prawidłowe:

Processing AdminController#doajaxing_for_updateuser (for 127.0.0.1 at 2010-03-22 17:37:13) [PUT]
Parameters: {“account”=>{“company_attributes”=>{“nip”=>“634-119-69-92”}}, “named”=>“company|nip”, “locale”=>“pl”}

Processing AdminController#doajaxing_for_createuser (for 127.0.0.1 at 2010-03-22 17:31:33) [POST]
Parameters: {“account”=>{“company_attributes”=>{“nip”=>“634-119-69-95”}}, “named”=>“company|nip”, “locale”=>“pl”}

I wszystko fajnie by było, jednak validacja przeprowadzana jest zawsze, niezależnie od tego czy żądanie było dla POST czy PUT

Ma ktoś pomysł dlaczego ?

samą walidację wywołuję poprzez

@model.valid?

a response zwracam z wiadomością z czegoś w postaci:

@model.errors[current]

Chciałbym żeby przebiegała tylko dla POST of course

Pozdrawiam

Czyli chesz przeprowadzać walidację pola :regon tylko przy tworzeniu rekordu, nie przy aktualizacji ? W modelu nie da się sprawdzić czy request.post? bo model nie ma dostępu do zmiennej request. Ale możesz użyć sposobu z validations tu skip, opisane w tych linkach http://rubyonrails.pl/forum/p17369-2010-03-09-19%3A37%3A44#p17369 i http://www.tonyamoyal.com/2009/12/03/ruby-on-rails-skipping-validations-based-on-where-object-is-created/ .

czyli u Ciebie będzie @model.validations_to_skip = [:nip, :regon] (nie zapomniej dodać accesora jak opisano w ostatnim poście z tych wyżej) przed wywołaniem @model.valid. Nie jestem pewny czy zadziała, ja używałem przed @mode.update_attributes

Widze sebcioz coś zaczął w tym kierunku też kombinować :slight_smile: http://rubyonrails.pl/forum/t2812-Validations-To-Skip

AdminController#doajaxing_for_updateuser jest beeee, tzn. tak się pisało aplikacje zanim powstały Rails Resources i “Restful controllers”.

Pluginy typu validations_to_skip mogą być czasami przydatne ale wg. mnie powinieneś po prostu trzymać się reguły max 7 akcji w kontrolerze (index, show, edit, update, new, create, destroy) i pominąć ręczne sprawdzanie walidacji przy pomocy #valid? (bo to wywołuje twój problem imho - oczywiście bez kodu ciężko coś napisać więcej). No chyba że masz wyjątkową sytuację i potrzebujesz jakichś dodatkowych akcji. Wklej kod to napiszemy więcej.

Problem rozwiązałem w ten sposób, że dodałem jednak pole w inputach, które nie mają być sprawdzane ajaxem podczas edycji. Da się to obejść udostępniając właśnie request modelom, ale ogólnie gdzieś przeczytałem, że tego nie polecają. Więc stwierdziłem, iż zubożenie funkcjonalności w edycji dla dwóch pól nie będzie taką wielką tragedią. Przy tworzeniu rekordu problemów nie mam ponieważ nie istnieje mój problem kolizji, kolizja pojawia się dlatego, że:

Mamy w bazie 20 firm z nipami, chcę edytować jedną firemkę z nich… otwieram form, zmieniam nazwę, przez przypadek kliknąłem w nip i teraz wchodzi ajax. Sprawdza mi unikatowość dla całej bazy włączając w to bieżącą edytowaną pozycję - wniosek - nie mogę tego nipu już tu wpisać jeśli go zmieniłem(nie wysłałem) i znów zmieniłem na poprawny stary…jest to minus zintegrowania przeze mnie modelu AR z ajaxem.

Innym rozwiązaniem jest zmienienie ajaxowej metody, aby dla wybranych pól przekazywała również wartość “przed zmianami” i dodawała ją do zapytania o valid? jednak wtedy nie mógłbym korzystać z pierwotnej metody AR validates_uniqueness_of i musiałbym pisać workaroundy dla każdego takiego przypadku.

@hosiawak:

ja używam czegoś takiego:

['page', 'account', 'category', 'unit', 'product', 'subcategory'].each do |hashed| define_method("doajaxing_for_"+hashed) do doajaxing(hashed) end end
doajaxing jest metodą mojego modułu

Nie uważam żeby było to takie tragiczne rozwiązanie, chciałem zintegrować walidację AR z ajaxem, dla każdego modelu nad którym chcę mieć taką kontrolę wywołuję doajaxing. Przyczyna jest prozaiczna nie lubię pisać w JS walidacji. Jeśli znacie inne rozwiązanie na taką integrację to będę wdzięczny za wskazówki. Przy okazji chciałbym nadmienić, że ów walidacja powinna być w pełni zsynchronizowana z locales dla railsów(nie dołączanie locales poprzez js - żadne jquery.Localisation mnie nie interesuje).

Pozdrawiam.

Walidacja w JS to jedno, a walidacja na poziomie Ruby to drugie.

Do i18n w JS możesz użyć http://github.com/qoobaa/javascript_i18n

[quote=rav]Walidacja w JS to jedno, a walidacja na poziomie Ruby to drugie.

Do i18n w JS możesz użyć http://github.com/qoobaa/javascript_i18n[/quote]
Ciekawe rozwiązanie, ale nadal nie rozumiem dlaczego walidacja w JS i w Rubym musi być “jednym” i “drugim” :> Dla mnie to w tej chwili jedno, wykorzystuję walidację danego modelu, mam całą walidację każdego formularza w jednym miejscu. Tworzenie nowych formularzy z ajaxową walidacją ogranicza się u mnie do stworzenia modelu i wywołania buildera dla forma, cały czas nie dotykając przy tym ani linijki kodu w JS.