shoulda nerada duplicitní chybové zprávy validací
Standardní validační hlášky v Ruby on Rails netřeba představovat. Je to super, člověk nemusí nic dělat, má je zadarmo. Na druhou stranu jsou také patřičně strojové a na skutečném webu zní velice zvláštně. Občas ani nemusí vystihovat, co je vlastně špatně.
Je proto běžné, že se pro jednotlivé validace v jednotlivých modelech píší chybové hlášky na míru. Ti pečlivější se je snaží co nejlépe sladit s kontextem, aby perfektně zapadly. Pro jeden atribut se pak třeba nevypisuje více než 1 chyba současně, vše je lokalizované a ideální.
Dá se však i narazit. Když pro různé validace jednoho atributu v témže modelu budete mít stejné chybové zprávy (protože to tak dává v daném kontextu smysl – např. lze sloučit informaci o nutnosti zadat údaj a že musí být číselný, tzn. „je třeba zadat číselný údaj“). Na první pohled není důvod k potížím, ale pokud poctivě testujete, může se to stát.
Přítomnost a konfiguraci validací testuji pomocí gemu shoulda
, což je ohromně jednoduché a pohodlné (na jeden řádek vše, co potřebuji). Nicméně shoulda kontroluje seznam chybových zpráv a hledá tam tu, která odpovídá dané testované validaci. Pokud mají dvě validace stejnou chybovou hlášku, splnění jedné z těchto validací shoulda
nepozná, protože její chybová zpráva v seznamu stále bude.
Tento problém se dá vyřešit drobným hackem – jednoduše všechny validační hlášky převést na unikátní, např. připojením jedinečného suffixu.
A přesně to provádí následující kód, který patří do test/test_helper.rb
:
class ActiveSupport::TestCase
def make_validation_messages_unique(model, locale = I18n.locale)
i = 0
I18n.get_backend.translations[locale][:activemodel][:errors][:models][model][:attributes].each do |attr, messages|
messages.each do |error, msg|
messages[error] = msg + '//' + i.to_s
i += 1
end
end
end
end
module I18n
module Base
def get_backend
backend = config.backend
backend.available_locales # to force load of translations
backend
end
end
class Backend::Simple
public :translations
end
end
Přičemž :activemodel
zde můžete chtít nahradit za :activerecord
– podle toho, kde přesně validujete.
V testu modelu pak stačí tento kód vždy ad-hoc zavolat:
setup do
make_validation_messages_unique :jmeno_modelu
end
Zaškatulkováno v kategorii: Ruby on Rails | 19. listopadu 2017