How to program in Portuguese in Ruby on Rails?

19

I would like to know how I can program an application in Ruby on Rails instead of English.

There are basically three issues to this:

  • How to change the user interface in Portuguese? (ActiveRecord error messages, dates and times in extensions, etc.)

  • How can I make pluralization work in Portuguese so that I can create names of tables and controllers in Portuguese? (For example: Usuario instead of User )

  • How do I change the routes from /edit to /editar and /new to /novo ?

  • asked by anonymous 07.06.2014 / 20:38

    1 answer

    30

    1 Changing the interface to Portuguese

    Create the file config/locales/pt-BR.yml and paste the following content there:

    pt-BR:
      # formatos de data e hora
      date:
        formats:
          default: "%d/%m/%Y"
          short: "%d de %B"
          long: "%d de %B de %Y"
    
        day_names: [Domingo, Segunda, Terça, Quarta, Quinta, Sexta, Sábado]
        abbr_day_names: [Dom, Seg, Ter, Qua, Qui, Sex, Sáb]
        month_names: [~, Janeiro, Fevereiro, Março, Abril, Maio, Junho, Julho, Agosto, Setembro, Outubro, Novembro, Dezembro]
        abbr_month_names: [~, Jan, Fev, Mar, Abr, Mai, Jun, Jul, Ago, Set, Out, Nov, Dez]
        order: [day, month, year]
    
      time:
        formats:
          default: "%A, %d de %B de %Y, %H:%M h"
          short: "%d/%m, %H:%M h"
          long: "%A, %d de %B de %Y, %H:%M h"
        am: ''
        pm: ''
    
      # distancia do tempo em palavras
      datetime:
        distance_in_words:
          half_a_minute: 'meio minuto'
          less_than_x_seconds:
            one: 'menos de 1 segundo'
            other: 'menos de %{count} segundos'
    
          x_seconds:
            one: '1 segundo'
            other: '%{count} segundos'
    
          less_than_x_minutes:
            one: 'menos de um minuto'
            other: 'menos de %{count} minutos'
    
          x_minutes:
            one: '1 minuto'
            other: '%{count} minutos'
    
          about_x_hours:
            one: 'aproximadamente 1 hora'
            other: 'aproximadamente %{count} horas'
    
          x_days:
            one: '1 dia'
            other: '%{count} dias'
    
          about_x_months:
            one: 'aproximadamente 1 mês'
            other: 'aproximadamente %{count} meses'
    
          x_months:
            one: '1 mês'
            other: '%{count} meses'
    
          about_x_years:
            one: 'aproximadamente 1 ano'
            other: 'aproximadamente %{count} anos'
    
          over_x_years:
            one: 'mais de 1 ano'
            other: 'mais de %{count} anos'
    
          almost_x_years:
            one: 'quase 1 ano'
            other: 'quase %{count} anos'
    
        prompts:
          year:   "Ano"
          month:  "Mês"
          day:    "Dia"
          hour:   "Hora"
          minute: "Minuto"
          second: "Segundos"
    
      # numeros
      number:
        format:
          precision: 3
          separator: ','
          delimiter: '.'
        currency:
          format:
            unit: 'R$'
            precision: 2
            format: '%u %n'
            separator: ','
            delimiter: '.'
        percentage:
          format:
            delimiter: '.'
        precision:
          format:
            delimiter: '.'
        human:
          format:
            precision: 2
            delimiter: '.'
            significant: true
            strip_unsignificant_zeros: true
          # number_to_human_size()
          storage_units:
            format: "%n %u"
            units:
              byte:
                one: "Byte"
                other: "Bytes"
              kb: "KB"
              mb: "MB"
              gb: "GB"
              tb: "TB"
          # number_to_human()
          # new in rails 3: please add to other locales
          decimal_units:
            format: "%n %u"
            units:
              unit: ""     
              thousand: "mil"
              million:
                one: milhão
                other: milhões
              billion:
                one: bilhão
                other: bilhões
              trillion:
                one: trilhão
                other: trilhões
              quadrillion:
                one: quatrilhão
                other: quatrilhões
    
      # Usado no Array.to_sentence
      support:
        array:
          words_connector: ", "
          two_words_connector: " e "
          last_word_connector: " e "
    
      # ActiveRecord
      activerecord:
        errors:
          template:
            header:
              one: "Não foi possível gravar %{model}: 1 erro"
              other: "Não foi possível gravar %{model}: %{count} erros."
            body: "Por favor, verifique o(s) seguinte(s) campo(s):"
          messages:
            inclusion: "não está incluído na lista"
            exclusion: "não está disponível"
            invalid: "não é válido"
            confirmation: "não está de acordo com a confirmação"
            accepted: "deve ser aceito"
            empty: "não pode ficar vazio"
            blank: "não pode ficar em branco"
            too_long: "é muito longo (máximo: %{count} caracteres)"
            too_short: "é muito curto (mínimo: %{count} caracteres)"
            wrong_length: "não possui o tamanho esperado (%{count} caracteres)"
            taken: "já está em uso"
            not_a_number: "não é um número"
            not_an_integer: "não é um número inteiro"
            greater_than: "deve ser maior do que %{count}"
            greater_than_or_equal_to: "deve ser maior ou igual a %{count}"
            equal_to: "deve ser igual a %{count}"
            less_than: "deve ser menor do que %{count}"
            less_than_or_equal_to: "deve ser menor ou igual a %{count}"
            odd: "deve ser ímpar"
            even: "deve ser par"
            record_invalid: "A validação falhou: %{errors}"
    

    Then go to config/application.rb and add the content below. This makes Brazilian Portuguese the default language of the application.

    config.i18n.default_locale = :"pt-BR"
    I18n.enforce_available_locales = false
    

    2 Changing Pluralization to Portuguese

    The config/initializers/inflections.rb file is responsible for telling Rails how it should pluralize / name names. Change it to the following content:

    # encoding: utf-8
    # Be sure to restart your server when you modify this file.
    
    # Add new inflection rules using the following format
    # (all these examples are active by default):
    # ActiveSupport::Inflector.inflections do |inflect|
    #   inflect.plural /^(ox)$/i, 'en'
    #   inflect.singular /^(ox)en/i, ''
    #   inflect.irregular 'person', 'people'
    #   inflect.uncountable %w( fish sheep )
    # end
    ActiveSupport::Inflector.inflections do |inflect|
      inflect.clear
    
      inflect.plural(/$/,  's')
      inflect.plural(/(s)$/i,  '')
      inflect.plural(/^(paí)s$/i, 'ses')
      inflect.plural(/(z|r)$/i, 'es')
      inflect.plural(/al$/i,  'ais')
      inflect.plural(/el$/i,  'eis')
      inflect.plural(/ol$/i,  'ois')
      inflect.plural(/ul$/i,  'uis')
      inflect.plural(/([^aeou])il$/i,  'is')
      inflect.plural(/m$/i,   'ns')
      inflect.plural(/^(japon|escoc|ingl|dinamarqu|fregu|portugu)ês$/i,  'eses')
      inflect.plural(/^(|g)ás$/i,  'ases')
      inflect.plural(/ão$/i,  'ões')
      inflect.plural(/^(irm|m)ão$/i,  'ãos')
      inflect.plural(/^(alem|c|p)ão$/i,  'ães')
    
      # Sem acentos...
      inflect.plural(/ao$/i,  'oes')
      inflect.plural(/^(irm|m)ao$/i,  'aos')
      inflect.plural(/^(alem|c|p)ao$/i,  'aes')
    
      inflect.singular(/([^ê])s$/i, '')
      inflect.singular(/^(á|gá|paí)s$/i, 's')
      inflect.singular(/(r|z)es$/i, '')
      inflect.singular(/([^p])ais$/i, 'al')
      inflect.singular(/eis$/i, 'el')
      inflect.singular(/ois$/i, 'ol')
      inflect.singular(/uis$/i, 'ul')
      inflect.singular(/(r|t|f|v)is$/i, 'il')
      inflect.singular(/ns$/i, 'm')
      inflect.singular(/sses$/i, 'sse')
      inflect.singular(/^(.*[^s]s)es$/i, '')
      inflect.singular(/ães$/i, 'ão')
      inflect.singular(/aes$/i, 'ao')
      inflect.singular(/ãos$/i, 'ão')    
      inflect.singular(/aos$/i, 'ao')
      inflect.singular(/ões$/i, 'ão')
      inflect.singular(/oes$/i, 'ao')
      inflect.singular(/(japon|escoc|ingl|dinamarqu|fregu|portugu)eses$/i, 'ês')
      inflect.singular(/^(g|)ases$/i,  'ás')
    
      # Incontáveis
      inflect.uncountable %w( tórax tênis ônibus lápis fênix )
    
      # Irregulares
      inflect.irregular "país", "países"
    end
    

    However, when creating tables and controllers with Portuguese names, you need to take some things into account:

    2.1 Not all words will be pluralized correctly

    Actually, this can happen even when programming in English. The ideal is to open the Rails console in your application ( rails console or rails c ) and check for pluralization.

    For example, type "usuario".pluralize and check that the output is "usuarios" . Then type "usuarios".singularize and check if the output is "usuario" .

    To avoid problems, if Rails is pluralizing wrong, before create tables and controllers include the following line in inflections.rb to force correct pluralization:

    inflect.irregular "usuario", "usuarios"
    

    Note: "user" is just an example, in fact it is already pluralized correctly.

    2.2 Caution when creating tables and controllers with more than one word in the name

    The pluralization of Rails works by taking English into account, where adjectives come before nouns. Therefore, it will only pluralize the last word of the name.

    If you want to create a student grade table, do not create the model as NotaDoAluno because Rails will erroneously pluralize as NotaDoAlunos . Instead create the model as AlunoNota , so it will pluralize as AlunoNotas . Same for controllers.

    If you know what you're doing, you can override the Rails table naming conventions . and manually set the table name for that template :

    class Product < ActiveRecord::Base
      self.table_name = "notas_do_aluno"
    end
    
    many-to-many tables

    Sometimes you may want to create a template for a many-to-many relationship, so you can add more fields or methods. It is common that in this case the name of the two tables is in the plural, for this use in inflections.rb :

    inflect.irregular "postagemtag", "postagenstags"
    inflect.irregular "postagem tag", "postagens tags"
    inflect.irregular "postagem_tag", "postagens_tags"
    

    So, when running rails generate , it will create names of tables and controllers with both words in the plural, otherwise only the last word would be pluralized.

    3 Changing routes to Portuguese

    This is easy, explained in official documentation . It will look something like this:

    resources :usuarios, path_names: { new: "novo", edit: "editar" }
    

    Or if you want you can change several at a time using scope :

    scope path_names: { new: "novo", edit: "editar" } do
      # seus resources
    end
    

    The variables _path are not changed, they continue with new and edit . For example: new_usuario_path and edit_usuario_path(@usuario) .

    Bonus - Setting Time Zone

    Rails by default displays and saves the hours in UTC time.

    If you want Rails to continue to save dates / times in UTC format, but convert to the user at another time, such as in Brasilia, use the code below in config/application.rb :

    config.time_zone = "Brasilia"
    

    This is a good idea if you need to support users from different countries.

    But if you want Rails both to store in the database and display the user in Brasília, use:

    config.time_zone = "Brasilia"
    config.active_record.default_timezone = :local
    

    This is necessary when you are working on a legacy base, which uses Brasília time in its date and time columns. Or if the base is own but you import data from another direct base via SQL, without being via ActiveRecord.

        
    07.06.2014 / 20:38