El módulo Inflectors de Ruby on Rails transforma palabras de singular a plural, nombres de clases a nombres de tablas, nombres de clases a claves foráneas, entre otros. Sin embargo éste módulo no soporta pluralización en español.
Si quieremos reemplazar la pluralización que trae por defecto Rails (inglés) y crear la nuestra en español solo debemos agregar estas reglas al final del archivo config/environment.rb:
La primera regla dice algo como: "Todas las palabras que terminen en t, a, e, i, o, u y que luego tengan una letra mayúscula, un underscore o un fin de línea entonces se pluralizan con S", mientras que la segunda regla dice: "Todas las palabras que terminen en r, l, n, d y que luego tengan una letra mayúscula, un underscore o un fin de línea entonces se pluralizan con ES". Las reglas tres y cuatro se interpretan siguiendo el mismo criterio pero de forma inversa. Así, "casa" se pluraliza como "casas" y "canción" se pluraliza como "canciones".
Dejaré como tarea para el lector estudiar de manera detallada las expresiones regulares usadas en las reglas, pero les dejaré una pista:
Con el código anterior ya tenemos configurada nuestra pluralización en español. Podemos probarla agregando el código a un proyecto existente y abriendo una consola de Rails:
Observamos que ahora el string 'prueba' está en plural. Sin embargo existe un bug en la versión 1.2.6 de Rails (quizás esté corregido en las versiones posteriores pero aún no lo he confirmado) y es que si intentamos pluralizar un string que contenga expresiones que cumplan ambos patrones del inflector entonces obtendremos una sola palabra pluralizada, por ejemplo:
Se debe extender la clase Inflector y modificar los métodos pluralize y singularize. El código lo podemos insertar en el mismo archivo config/environment.rb y sería algo como:
Si revisamos el código fuente de los métodos pluralize y singularize veremos que la diferencia está en la instrucción break if en las líneas 112 y 132 respectivamente:
Solo debemos eliminar ese par de instrucciones para que entonces la regla sea aplicable a más de un patrón al mismo tiempo.
Por los momentos es todo. Espero sea de utilidad este pequeño pero interesante tip
Si quieremos reemplazar la pluralización que trae por defecto Rails (inglés) y crear la nuestra en español solo debemos agregar estas reglas al final del archivo config/environment.rb:
# Limpiamos todas las inflecciones existentes
Inflector.inflections.clear
# Agregamos las reglas de inflección
Inflector.inflections do |inflect|
inflect.plural /([taeiou])([A-Z]|_|\$)/, '\1s\2'
inflect.plural /([rlnd])([A-Z]|_|$)/, '\1es\2'
inflect.singular /([taeiou])s([A-Z]|_|$)/, '\1\2'
inflect.singular /([rlnd])es([A-Z]|_|$)/, '\1\2'
end
La primera regla dice algo como: "Todas las palabras que terminen en t, a, e, i, o, u y que luego tengan una letra mayúscula, un underscore o un fin de línea entonces se pluralizan con S", mientras que la segunda regla dice: "Todas las palabras que terminen en r, l, n, d y que luego tengan una letra mayúscula, un underscore o un fin de línea entonces se pluralizan con ES". Las reglas tres y cuatro se interpretan siguiendo el mismo criterio pero de forma inversa. Así, "casa" se pluraliza como "casas" y "canción" se pluraliza como "canciones".
Dejaré como tarea para el lector estudiar de manera detallada las expresiones regulares usadas en las reglas, pero les dejaré una pista:
Es necesario recordar que en una expresión regular los paréntesis son signos de agrupación y cada expresión entre paréntesis corresponde a un grupo. Se puede hacer referencia a la expresión asociada a un grupo mediante una barra invertida "\" y el número del grupo. Es por eso que en la expresión regular del Inflector se usa el \1 y el \2
Con el código anterior ya tenemos configurada nuestra pluralización en español. Podemos probarla agregando el código a un proyecto existente y abriendo una consola de Rails:
$ cd proyecto_existente_de_rails
$ script/console
Loading development environment.
>>'prueba'.pluralize
=> "pruebas"
Observamos que ahora el string 'prueba' está en plural. Sin embargo existe un bug en la versión 1.2.6 de Rails (quizás esté corregido en las versiones posteriores pero aún no lo he confirmado) y es que si intentamos pluralizar un string que contenga expresiones que cumplan ambos patrones del inflector entonces obtendremos una sola palabra pluralizada, por ejemplo:
>>'prueba_cancion'.pluralize
=> "prueba_canciones"
Se debe extender la clase Inflector y modificar los métodos pluralize y singularize. El código lo podemos insertar en el mismo archivo config/environment.rb y sería algo como:
# Extender la clase Inflector
module Inflector
def pluralize(word)
result = word.to_s.dup
if word.empty? || inflections.uncountables.include?(result.downcase)
result
else
inflections.plurals.each { |(rule, replacement)| result.gsub!(rule, replacement) }
result
end
end
def singularize(word)
result = word.to_s.dup
if inflections.uncountables.include?(result.downcase)
result
else
inflections.singulars.each { |(rule, replacement)| result.gsub!(rule, replacement) }
result
end
end
end
Si revisamos el código fuente de los métodos pluralize y singularize veremos que la diferencia está en la instrucción break if en las líneas 112 y 132 respectivamente:
112: inflections.plurals.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
...
132: inflections.singulars.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
Solo debemos eliminar ese par de instrucciones para que entonces la regla sea aplicable a más de un patrón al mismo tiempo.
Por los momentos es todo. Espero sea de utilidad este pequeño pero interesante tip