Pozor, od 6. 6. 2025 bude můj web přístupný již jen v rámci skutečného Internetu – v historickém vypínám.

Můj malý svět

Obrať obličej k slunci
a stíny budou padat za tebe
  • Eko náhrady
  • Stop Heuréce
  • Zkušenosti s firmami
  • 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

    Komentáře

    Jak přidat komentář? E-mailem! :·) Na komentare -zavináč- mujmalysvet -tečka- cz – do předmětu „Komentář: shoulda nerada duplicitní chybové zprávy validací“. Připojit můžete i svou přezdívku a domovskou stránku.