Blog jak widać już nie jest aktualizowany. I raczej nie będzie. Wisi sobie ot tak, ze względów historycznych :)

Ruby on Rails - własne komunikaty o błędach

Krzysztof Rygielski | 2009-11-20 12:23 | Kategorie: Rails, Ruby

Ostatnio potrzebowałem dodać do walidacji formularza własny komunikat o błędzie. Mechanizm RoR pozwala na to, jednak nie jest to takie oczywiste, jak mogłoby wynikać z dokumentacji.

Gdy pogrzebałem w dokumentacji rails i w google oczywiste się stało, że jeśli chcemy dodać wiadomość o błędzie, nie powiązaną z żadnym polem modelu, należy postąpić mniej więcej tak:

@post.errors.add :base, "Wystąpił jakiś błąd"

I niby jest ok. JeÅ›li jednak uruchomimy metodÄ™ save modelu i zostanie przeprowadzona walidacja pozostaÅ‚ych pól, to nasz dodatkowy komunikat zniknie. JeÅ›li konstrukcja bÄ™dzie wyglÄ…dać mniej wiÄ™cej tak:

@post.errors.add :base, "Wystąpił jakiś błąd"

if @post.save
...
end

To wywoÅ‚anie save nadpisze obiekt errors modelu i metoda error_messages_for nie wypisze naszego komunikatu. Ja postÄ…piÅ‚em ciut inaczej. DorobiÅ‚em sobie wÅ‚asnÄ… metodÄ™ w modelu, która zaÅ‚óżmy, że sprawdza wartość jakiegoÅ› parametru, który nie jest polem w modelu:

class Post < ActiveRecord::Base
  ...
  def custom_validation(parametr)
    if parametr.blank?
      self.valid?
      self.errors.add :base, "Parametr nie może być pusty"
      return false
    else
      return true
    end
  end
end

Czyli wywoÅ‚ujÄ™ metodÄ™ valid? modelu, aby przeprowadzić od razu walidacjÄ™ pozostaÅ‚ych pól i wypeÅ‚nić zbiór bÅ‚Ä™dów przed dodaniem do niego wÅ‚asnego komunikatu o bÅ‚Ä™dzie. NastÄ™pnie w kontrolerze:

if @post.custom_validation(params[:parametr]) and @post.save
...
end

Wówczas już w wywoÅ‚aniu naszej funkcji, jeÅ›li zwróci wartoÅ›c false, już bÄ™dziemy mieć peÅ‚en komplet komunikatów o bÅ‚Ä™dzie do wypisania w error_messages_for a metoda save nie zostanie wywoÅ‚ana, gdyż już pierwsze zdanie koniunkcji bÄ™dzie faÅ‚szywe. JeÅ›li zwróci true, to dopiero odpalana jest metoda save modelu.

OczywiÅ›cie, nie żebym sam to wymyÅ›liÅ‚ :-) PodejrzaÅ‚em to rozwiÄ…zanie w kodzie źródÅ‚owym pluginu recaptcha, gdzie w metodzie verify_recaptcha rozwiÄ…zano to w podobny sposób.