ruby-on-rails – How to program in Portuguese in Ruby on Rails?

Question:

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

There are basically three problems with this:

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

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

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

Answer:

1 Changing the interface to Portuguese

Create the 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 is responsible for telling Rails how it should pluralize/singularize the 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, '\1en'
#   inflect.singular /^(ox)en/i, '\1'
#   inflect.irregular 'person', 'people'
#   inflect.uncountable %w( fish sheep )
# end
ActiveSupport::Inflector.inflections do |inflect|
  inflect.clear

  inflect.plural(/$/,  's')
  inflect.plural(/(s)$/i,  '\1')
  inflect.plural(/^(paí)s$/i, '\1ses')
  inflect.plural(/(z|r)$/i, '\1es')
  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,  '\1is')
  inflect.plural(/m$/i,   'ns')
  inflect.plural(/^(japon|escoc|ingl|dinamarqu|fregu|portugu)ês$/i,  '\1eses')
  inflect.plural(/^(|g)ás$/i,  '\1ases')
  inflect.plural(/ão$/i,  'ões')
  inflect.plural(/^(irm|m)ão$/i,  '\1ãos')
  inflect.plural(/^(alem|c|p)ão$/i,  '\1ães')

  # Sem acentos...
  inflect.plural(/ao$/i,  'oes')
  inflect.plural(/^(irm|m)ao$/i,  '\1aos')
  inflect.plural(/^(alem|c|p)ao$/i,  '\1aes')

  inflect.singular(/([^ê])s$/i, '\1')
  inflect.singular(/^(á|gá|paí)s$/i, '\1s')
  inflect.singular(/(r|z)es$/i, '\1')
  inflect.singular(/([^p])ais$/i, '\1al')
  inflect.singular(/eis$/i, 'el')
  inflect.singular(/ois$/i, 'ol')
  inflect.singular(/uis$/i, 'ul')
  inflect.singular(/(r|t|f|v)is$/i, '\1il')
  inflect.singular(/ns$/i, 'm')
  inflect.singular(/sses$/i, 'sse')
  inflect.singular(/^(.*[^s]s)es$/i, '\1')
  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, '\1ês')
  inflect.singular(/^(g|)ases$/i,  '\1á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 a few things into account:

2.1 Not all words will be pluralized correctly

In fact, 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 the pluralization.

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

To avoid problems, if Rails is pluralizing wrongly, before creating the tables and controllers add the following line to 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 Be careful when creating tables and controllers with more than one word in the name

Rails pluralization 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 table of student grades, don't create the template as NotaDoAluno as Rails will mistakenly pluralize as NotaDoAlunos . Instead create the template as AlunoNota so it will pluralize as AlunoNotas . Ditto for controllers.

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

class Product < ActiveRecord::Base
  self.table_name = "notas_do_aluno"
end

2.3 many-to-many tables

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

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

Thus, when running rails generate , it will create table and controller names with both words pluralized, otherwise only the last word would be pluralized.


3 Changing routes to Portuguese

That's easy, it's explained in the 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 once using scope :

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

The _path variables 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 stores the hours in UTC time in the database.

If you want Rails to keep saving dates/times in UTC format, but convert them to another time, such as Brasília, 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.

However, if you want Rails to both store it in the bank and display it to the user in Brasília time, use:

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

This is necessary when you are working on a legacy basis, which uses Brasilia time in its date and time columns. Or if the database is your own but you import data from another database directly via SQL, not via ActiveRecord.

Scroll to Top