Ruby on Rails PL Forum

Forum poświęcone Ruby on Rails i językowi programowania Ruby

Nie jesteś zalogowany.

#1 2006-01-06 00:18:22

balcer
Obserwator
Zarejestrowany: 2006-01-06
Posty: 3

Jak uniknąć angielskich komunikatów o błędach

Nie jest to najlepszy sposób bo nie powinno się tak robić ale smile :
W application.rb naleÂży przeciżyć dwie metody np w taki sposób
class ApplicationController < ActionController::Base
....
class ActionView::Base
        def error_messages_for(object_name, options = {})
            options = options.symbolize_keys
            object = instance_variable_get("@#{object_name}")               
            unless object.errors.empty?
            content_tag("div",
                 content_tag(
                   options[:header_tag] || "h2",
                   "Wystąpiła następująca ilość błędów związanych z obiektem '#{object_name.to_s.gsub("_", " ")}': #{object.errors.count}"
                 ) +
                 content_tag("p", "Wystąpił problem z następującymi polami") +
                 content_tag("ul", object.errors.full_messages.collect { |msg| content_tag("li", msg) }),
                 "id" => options[:id] || "errorExplanation", "class" => options[:class] || "errorExplanation"
               )              
            end
        end
    end   
   
    class ActiveRecord::Errors       
        def full_messages
           full_messages = []
           @errors.each_key do |attr|
             @errors[attr].each do |msg|
                   next if msg.nil?
                   if attr == "base"
                     full_messages << msg
                   else
                     full_messages << msg
                   end
             end
           end
           return full_messages
         end
    end     
....
end

Pierwsza definiuje message o błędach, druga pozwala na uniknięcie nazw zmiennych podczas wyświetlania błędów.
Może ktoś zna lepszy sposób, właśnie wrociłem do pisania stronki po jakichś 2 miesiącach przerwy. Coś sie ruszyło z internacjonalizacją, szczegłlnie na polu zakodowanych na sztywno messegów ?
Pozdrawiam, Jacek Balcerski

Offline

 

#2 2006-01-26 10:51:08

daniel
Obserwator
Zarejestrowany: 2006-01-26
Posty: 74
Serwis

Re: Jak uniknąć angielskich komunikatów o błędach

Moja propozycja rozwiazania (podpatrzona gdzies w trzewiach sieci):

1. nowy folder w app/exts
2. w nim tworzymy plik all.rb z zawartoscia:

Kod: "ruby"

  1. Dir[File.dirname(__FILE__) + "/**/*.rb"].each { |file| require(file) }

3. przystepujemy do prawdziwej zmiany - w app/exts tworzymy folder active_record, a w nim plik validations.rb - w ten sposob utrzymujemy konwencje z railsow; zawartosc app/exts/validations.rb:

Kod: "ruby"

  1. module ActiveRecord
  2. class Errors
  3. begin
  4. # tlumaczenia ofcoz trzeba dokonac samodzielnie...
  5. @@default_error_messages.update( {
  6. :inclusion => "is not included in the list",
  7. :exclusion => "is reserved",
  8. :invalid => "is invalid",
  9. :confirmation => "doesn't match confirmation",
  10. :accepted => "must be accepted",
  11. :empty => "can't be empty",
  12. :blank => "can't be blank",
  13. :too_long => "is too long (max is %d characters)",
  14. :too_short => "is too short (min is %d characters)",
  15. :wrong_length => "is the wrong length (should be %d characters)",
  16. :taken => "has already been taken",
  17. :not_a_number => "is not a number"
  18. })
  19. end
  20. alias :old_on_blank :add_on_blank
  21. # a to jest moja wersja metody ktora nie robi nic sensownego ale pokazuje
  22. # jakby co - to mozna ;)
  23. def add_on_blank(attributes, msg = @@default_error_messages[:empty])
  24. old_on_blank(attributes, msg)
  25. end
  26. end
  27. end

4. dodajemy obsluge naszych swiezych zmian do aplikacji - w pliku app/config/environment.rb na koncu dodajemy linijke wlaczajaca nasze zmiany:

Kod: "ruby"

  1. require "#{RAILS_ROOT}/app/exts/all"

Taki sposob podejscia pozwala utrzymac w jednym miejscu wszystkie modyfikacje orginalnego zachowania railsow. Tworzy sie plik i umieszcza w stosownym katalogu pod app/exts i voila - wlaczone i zaaplikowane...

oops to moj pierwszy post - wiec witam wszystkich bardzo serdecznie !!

happy railing
-- daniel

Offline

 

#3 2006-05-07 14:01:31

cr
Obserwator
Zarejestrowany: 2006-05-07
Posty: 1

Re: Jak uniknąć angielskich komunikatów o błędach

daniel napisał:

Taki sposob podejscia pozwala utrzymac w jednym miejscu wszystkie modyfikacje orginalnego zachowania railsow.

...i pozwala później na szybkie przekształcenie tej modyfikacji w plugina wink

Offline

 

#4 2007-06-13 23:49:30

sandman
Obserwator
Zarejestrowany: 2007-06-13
Posty: 3

Re: Jak uniknąć angielskich komunikatów o błędach

cr napisał:

daniel napisał:

Taki sposob podejscia pozwala utrzymac w jednym miejscu wszystkie modyfikacje orginalnego zachowania railsow.

...i pozwala później na szybkie przekształcenie tej modyfikacji w plugina wink

Witam rubberów!
czy wie ktoś może jak przetłumaczyć nazwy kolumn i tabel, tak aby w walidacji nie pojawiało mi się password a hasło, chociaż w bazie mam nazwę password. Doinstalowałem plugin Globalize i chcę mieć wszystko w 2 językach.
Dzięki!

Offline

 

#5 2007-06-14 01:20:18

Paweł Kondzior
Cobra Commander
Od: Warszawa
Zarejestrowany: 2006-03-11
Posty: 803
Serwis

Re: Jak uniknąć angielskich komunikatów o błędach

zacznij uzywac :message w validacjach ? smile pozatym polecam gettext :-)

np uzywajac gettext zrobil bys to tak:

validation_presence_of :password, :message => _('Field Password Can't Be Blank')

Oczywiscie doradzam wtedy napisanie wlasnego helper'a do error_messages_for()

Globalize stanowczo odradzam poniewaz jest to rozwiazanie oparte na bazie danych i strasznie niewydajne.


irb(main):001:0>

Offline

 

#6 2007-06-14 02:39:46

hipertracker
Administrator
Od: Irlandia
Zarejestrowany: 2006-01-10
Posty: 217
Serwis

Re: Jak uniknąć angielskich komunikatów o błędach

PaK napisał:

Globalize stanowczo odradzam poniewaz jest to rozwiazanie oparte na bazie danych i strasznie niewydajne.

Poważnie? Ja nie zauważyłem jakiejś słabej wydajności. Zwykle pobierane są krótkie teksty, są poindeksowane. Relacyjna baza danych jest bardzo szybka, bo wykorzystuje własny cache do takich niedużych operacji.

To, że używana jest baza danych to tylko zaleta. Np. proces tłumaczenia nie wymaga co chwilę restartowania Mongrela aby zmiany były widoczne w serwisie. Gettext nadaje się tylko do tłumaczenia interfejsu. Globalize pozwala zaś też tworzyć wiele wersji językowych dla tekstów trzymanych w bazie mi ładnie te wersje się przełączają.

Offline

 

#7 2007-06-14 09:13:53

Paweł Kondzior
Cobra Commander
Od: Warszawa
Zarejestrowany: 2006-03-11
Posty: 803
Serwis

Re: Jak uniknąć angielskich komunikatów o błędach

No ja sie zgadzam ze gettextu nie nalezy uzywac do tworzenia roznych dokumentow juz bezposrednio na strone, natomiast przeciez jest to standardowy system lokalizawania walsnie interfejsu, ale sa gusta i gusciki wink Ja sie zrazilem do globalize ;-)


irb(main):001:0>

Offline

 

#8 2007-06-22 19:07:14

sabon
Obserwator
Od: Warszawa
Zarejestrowany: 2006-03-23
Posty: 70
Serwis

Re: Jak uniknąć angielskich komunikatów o błędach

balcer napisał:

Nie jest to najlepszy sposób bo nie powinno się tak robić ale smile :
W application.rb naleÂży przeciżyć dwie metody np w taki sposób
class ApplicationController < ActionController::Base
....
class ActionView::Base
        def error_messages_for(object_name, options = {})
(...)   
    class ActiveRecord::Errors       
(...)
end

Pierwsza definiuje message o błędach, druga pozwala na uniknięcie nazw zmiennych podczas wyświetlania błędów.
Może ktoś zna lepszy sposób, właśnie wrociłem do pisania stronki po jakichś 2 miesiącach przerwy. Coś sie ruszyło z internacjonalizacją, szczegłlnie na polu zakodowanych na sztywno messegów ?
Pozdrawiam, Jacek Balcerski

Siedziałem nad tym ładnych parę godzin. I już praktycznie doszedłem do tego samego, ale ten post pozwolił mi to skończyć trochę wcześniej, niż jakbym robił to sam smile
Według mnie trochę to bez sensu,  że nie można ustawić np. error_messages_for i parametru :base (żeby nie pokazywał nazw kolumn), no ale cóż...

Aha, jako że to mój pierwszy post, to witam wszystkich. Pewnie zacznę częściej tu się pojawiać.

Sabon

Offline

 

#9 2007-10-17 16:11:56

lordoza
Obserwator
Zarejestrowany: 2007-10-17
Posty: 2

Re: Jak uniknąć angielskich komunikatów o błędach

aby zmienić nazwy pól wyświetlanych w błędach można spróbować takiego rozwiązania
jesli mamy model user
w pliku user.rb
class User < ActiveRecord::Base
...
  validates_presence_of     :login, :message => "nie powinno byc puste"
  validates_presence_of     :email, :message => "nie powinno byc puste"
  validates_presence_of     :password,                   :if =>
...
end
class << self
    HUMANIZED_ATTRIBUTE_KEY_NAMES = {
      "password" => "Pole hasła" ,
      "email"  => "Pole adresu email" ,
      "password_confirmation" => "Pole potwierdzenia hasła"
    }
    def human_attribute_name(attribute_key_name)
      HUMANIZED_ATTRIBUTE_KEY_NAMES[attribute_key_name] || super
    end
end


btw Mój pierwszy post tutaj witam Wszystkich :-)

Ostatnio edytowany przez lordoza (2007-10-17 16:38:17)

Offline

 

#10 2007-10-17 18:50:40

seban
Entuzjasta
Od: Gdańsk
Zarejestrowany: 2006-07-26
Posty: 376
Serwis

Re: Jak uniknąć angielskich komunikatów o błędach

a coś takiego:

Kod:

validates_presence_of :something, :message => "^Coś nie powinno być puste"

Daszek ^ chyba sprawi, że w message nie pojawi się nazwa zmiennej?

Offline

 

#11 2007-10-21 15:44:24

ruthrsc
Bywalec
Od: Warszawa
Zarejestrowany: 2006-02-04
Posty: 207
Serwis

Re: Jak uniknąć angielskich komunikatów o błędach

seban napisał:

a coś takiego:

Kod:

validates_presence_of :something, :message => "^Coś nie powinno być puste"

Daszek ^ chyba sprawi, że w message nie pojawi się nazwa zmiennej?

AFAIR do tego chyba trzeba cos spatchowac / wrzucic plugin, bo natywnie tego nie ma.

Offline

 

#12 2007-10-22 02:50:44

pawel
Adept
Od: Krakow
Zarejestrowany: 2006-01-28
Posty: 155
Serwis

Re: Jak uniknąć angielskich komunikatów o błędach

Jest taki plugin ale wystarczy wsadzic do liba:

Kod:

module ActiveRecord
  class Errors
    def full_messages_with_custom
      full_messages = []

      @errors.each_key do |attr|
        @errors[attr].each do |msg|
          next if msg.nil?
          
          if attr == "base"
            full_messages << msg
          elsif msg =~ /^\^/ # TUTAJ
            full_messages << msg[1..-1]
          else
            full_messages << @base.class.human_attribute_name(attr) + " " + msg
          end
        end
      end
      return full_messages
    end
    alias_method_chain :full_messages, :custom 
  end
end

... ale jak ktos dodatkowo uzywa gettexta, to:

Kod:

require 'gettext/active_record'

module ActiveRecord
  class Errors
    include GetText
    
    def localize_error_message(attr, msg, append_field) # :nodoc:
      custom_msg = nil
      #Ugly but... :-<
      @@default_error_messages_d.dup.merge(@base.custom_error_messages_d).each do |key, regexp|
        if regexp =~ msg
          custom_msg = @base.gettext(key)
          custom_msg = _(msg) if custom_msg == msg 
            custom_msg = _(custom_msg) % $1.to_i
          break
        end
      end

      unless custom_msg
        custom_msg = @base.gettext(msg)
        custom_msg = _(msg) if custom_msg == msg 
      end
      if attr == "base"
        full_message = custom_msg
      elsif /^\^/ =~ custom_msg
        full_message = custom_msg[1..-1]
      elsif /%\{fn\}/ =~ custom_msg
        full_message = custom_msg % {:fn => @base.class.human_attribute_name(attr)}
      elsif append_field
        full_message = @base.class.human_attribute_name(attr) + " " + custom_msg
      else
        full_message = custom_msg
      end
      full_message
    end    
  end
end

------------------------------------------------------------------------------------
Java Developers can produce Powerful + Complex  Web Applications ... slowly.

Offline

 

#13 2008-07-31 12:29:53

mazzy
Obserwator
Od: Pszczyna
Zarejestrowany: 2007-10-03
Posty: 28
Serwis

Re: Jak uniknąć angielskich komunikatów o błędach

Polecam nam naszego plugina do zamiany komunikatów ActiveRecord na dowolny język:

http://github.com/ncr/gibberish_trix/tree/master
(wymagane jest zainstalowanie tego pluginu w pierwszej kolejnosci)

Jeśli używacie Gibberisha plugin ten będzie dla was idealny!

Przetłumaczy dla was automatycznie komunikaty w stylu (ponizsze stringi zamiencie na polski):


...

error_blank: "nie może być puste"
error_too_long: "jest zbyt długie (maksimum to %d znaków)"
error_taken: "jest już zajęte"

...

Co wiecej przetłumaczy wam automatycznie labele do formularzy smile
Zakladajac, ze macie 2 modele User, i Product, gdzie obydwa maja pole: body
Dodajcie do pliku z tlumaczeniem: "attr_#{table_name.singularize}_#{attribute_key_name}". Np:

attr_user_name: Imię i Nazwisko
attr_product_name: Nazwa produktu

inne pluginy tego typu, które pozwalaja na podobne rzeczy (np. globalite) obydwa pola przetłumaczylyby wam jako: Nazwa ...


TRIX - aplikacje Ruby on Rails, marketing

Offline

 

#14 2008-08-20 01:03:36

sabon
Obserwator
Od: Warszawa
Zarejestrowany: 2006-03-23
Posty: 70
Serwis

Re: Jak uniknąć angielskich komunikatów o błędach

Jak dla mnie najmniej inwazyjnym sposobem jest przeciążenie ActionView::Base i ActiveRecord::Errors, gdzie w 'Errors' pomija się nazwy zmiennych (przeważnie angielskie, bo tak konstruuję swoją bazę).
Wtedy w bardzo prosty sposób przy każdym validates_* dodaję :message, gdzie zawieram nazwę zmiennej, np.: validates_presence_of_password, :message => "Hasło nie może być puste".
Proste, nieinwazyjne i nie trzeba w kilku miejscach tłumaczyć nazw zmiennych i pamiętać o spójności.
Pytanie tylko czy to w końcu zostało ujęte w jakimś prostym pluginie czy ciągle trzeba to wrzucać do environment.rb (tudzież app/exts).

PS. Ktokolwiek jest odpowiedzialny za ustawienia forum, powinien poprawić godzinę na serwerze. Jest 2 godz. do tyłu.

Ostatnio edytowany przez sabon (2008-08-20 01:05:26)

Offline

 

#15 2009-07-14 13:13:33

Paweł Kondzior
Cobra Commander
Od: Warszawa
Zarejestrowany: 2006-03-11
Posty: 803
Serwis

Re: Jak uniknąć angielskich komunikatów o błędach

Jeszcze inna propozycja rozwiazania (chociaz podobna do jednej z poprzednich)

Kod:

module ServiceDesk #:nodoc:
  module Humanizer
    def self.included(base) # :nodoc:
      base.extend ClassMethods
    end

    module ClassMethods
      def humanize(attributes)
        attributes.stringify_keys!
        if read_inheritable_attribute(:human_attribute_names).nil?
          class_inheritable_reader(:human_attribute_names)
          write_inheritable_attribute(:human_attribute_names, attributes)
          self.class_eval do
            def self.human_attribute_name(attr)
              self.human_attribute_names[attr] || super(attr)
            end
          end
        else
          write_inheritable_attribute(:human_attribute_names, read_inheritable_attribute(:human_attribute_names).merge(attributes))
        end
      end
    end
  end
end

ActiveRecord::Base.send(:include, ServiceDesk::Humanizer)

w praktyce wyglada to tak:

Kod:

class Ticket < ActiveRecord::Base
  humanize({
      :location_name => "Location"
    })
end

class Ticket2 < Ticket
  humanize({
      :requestor_name => "Requestor"
    })
end

Kod:

>> Ticket.human_attribute_name("location_name")
=> "Location"
>> Ticket.human_attribute_name("requestor_name")
=> "Requestor name"
>> Ticket2.human_attribute_name("requestor_name")
=> "Requestor"

irb(main):001:0>

Offline

 

#16 2009-07-14 13:33:32

drogus
Moderator
Od: Pruszków
Zarejestrowany: 2005-12-01
Posty: 1739
Serwis

Re: Jak uniknąć angielskich komunikatów o błędach

Na dzień dzisiejszy to chyba lekko zbędny kod smile

Railsy korzystają z tłumaczeń i18n domyślnie i korzystając z nich można bez problemu przetłumaczyć nazwy pól.

Offline

 

#17 2009-07-14 16:05:00

Paweł Kondzior
Cobra Commander
Od: Warszawa
Zarejestrowany: 2006-03-11
Posty: 803
Serwis

Re: Jak uniknąć angielskich komunikatów o błędach

drogus napisał:

Na dzień dzisiejszy to chyba lekko zbędny kod smile

Railsy korzystają z tłumaczeń i18n domyślnie i korzystając z nich można bez problemu przetłumaczyć nazwy pól.

Nie korzystam z i18n, kiepsko sie skaluje na plikach tekstowych, majac 6000 string'ów w aplikacji było by mi bardzo trudno tym zarządzać. Gettext w tym przypadku jest znacznie lepszy. IMHO i18n w rails to niewypał.


irb(main):001:0>

Offline

 

#18 2009-11-16 19:51:01

wojtasek
Obserwator
Zarejestrowany: 2009-11-16
Posty: 13

Re: Jak uniknąć angielskich komunikatów o błędach

Szukałem na necie rozwiązania dla małych aplikacji i nie doszukałem się niczego prostego co bym mógł zakumać.
Zrobiłem to po swojemu (popatrzyłem w źródła validation.rb).

Piszę tutaj, bo może akurat ktoś będzie miał podobny problem.

Ogólnie chodziło o to, że to co jest w standardowym pl.yml to nie za bardzo pasuje nawet do standardowego restfull authentication.
"{attribute} {message}" = "Email nie może być puste", itp. smile

Może da się to inaczej zrobić, ale dla mnie jest idealne rozwiązanie, gdyż pasuje do kazdej opcji. Nie muszę się trzymać schematu "{attribute} {message}". Dodatkowo {message} w tym standardowym pl.yml musi być taki aby pasował do wszystkich {attribute} (jeżeli dobrze rozumiem), co w języku polskim jest niewygodne ("Email jest pustY", "Hasło jest pustY", muszą być inne {message}).

Wynik jest tutaj: http://programmers-blog.com/2009/11/16/ … sages-i18n

Offline

 

Stopka forum

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson