Ruby on Rails - własne komunikaty o błędach
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.