# General Translation Knowledge Base: General Translation vs. Mobility: ¿cuál deberías usar?
URL: https://generaltranslation.com/es/kb/general-translation-vs-mobility.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Mobility almacena los atributos traducidos de los modelos en tu base de datos. General Translation genera esas traducciones a través de su API, usando tu glosario y tus prompts personalizados. Usa ambos para traducir fichas de productos, publicaciones y otro contenido de la base de datos sin renunciar a tus modelos de Rails.
Category: Internacionalización
Last updated: 2026-10-16
Authors: Kevin Wu, Jackie Chen
Published: 2026-10-16

Mobility es una gema de Ruby para traducir los datos de tu base de datos: declaras `translates :title` en un modelo y `post.title` devuelve el título en la configuración regional actual, leído desde el backend de almacenamiento que elijas. Mobility almacena y recupera las traducciones, pero escribirlas corre a cargo de tus editores, de tus traductores o de un servicio. General Translation las proporciona a través de su API HTTP. Mobility guarda los atributos traducidos en tu base de datos actual, listos para usarse con las mismas consultas y métodos de modelo de siempre.

## Lo que Mobility hace bien

* **Varias opciones de almacenamiento.** El backend predeterminado `key_value` [guarda todas las traducciones en dos tablas compartidas](https://github.com/shioyama/mobility/wiki/KeyValue-Backend) (una para cadenas y otra para texto). El backend `table` usa una tabla de traducciones por modelo (el enfoque de Globalize), `column` usa columnas con sufijo, como `title_en` y `title_es`, `serialized` las guarda en una sola columna de texto y, en PostgreSQL, `json`, `jsonb`, `hstore` y `container` (una columna jsonb por modelo) las almacenan de forma nativa. También puedes escribir tu propio backend.
* **Una sola API para todos los backends.** Las lecturas y escrituras siguen `I18n.locale`, y los plugins (alternativas de respaldo, accesores por configuración regional como `post.title_es`, seguimiento de cambios, caché y comprobaciones de presencia) [funcionan igual sea cual sea el backend que elijas](https://github.com/shioyama/mobility#backends).
* **Consultas.** [`Post.i18n.where(title: "...")`](https://github.com/shioyama/mobility#querying) genera los joins para la configuración regional actual, así que puedes buscar en atributos traducidos sin saber cómo están almacenados.
* **Compatibilidad con ORM.** [Funciona con Active Record 7.0 o posterior y con Sequel](https://github.com/shioyama/mobility#installation), y su wiki incluye una guía para migrar desde Globalize.
* **Gratuito.** Tiene licencia MIT; la [versión actual es la 1.3.2](https://rubygems.org/gems/mobility).

## Lo que Mobility deja en tus manos

Aquí tienes una publicación con título y cuerpo en inglés, que usa el backend `key_value` sobre SQLite y que, solo para el título, recurre al inglés cuando no hay versión en español:

```ruby title="app/models/post.rb"
class Post < ApplicationRecord
  extend Mobility
  translates :title, type: :string, fallbacks: { es: :en }
  translates :body,  type: :text
end
```

```ruby
post = Post.create!(title: "Spring sale", body: "Everything is 20% off this week.")

I18n.with_locale(:es) { post.title } # => "Spring sale" (en inglés, por el fallback)
I18n.with_locale(:es) { post.body }  # => nil
I18n.with_locale(:ja) { post.title } # => nil
```

Ese es el comportamiento correcto para una capa de almacenamiento: Mobility guardó los valores en inglés, y todas las demás configuraciones regionales permanecen vacías hasta que alguien las rellene. Con un contenido alternativo, los lectores en español ven el texto en inglés; sin él, no ven nada. Para el contenido que cambia a diario, como fichas de productos, artículos o páginas de ayuda, alguien tiene que traducir cada registro nuevo o modificado a cada idioma y guardarlo en la configuración regional correspondiente.

## Completar atributos de Mobility con General Translation

El endpoint de traducción en tiempo de ejecución de General Translation, `POST https://api.gtx.dev/v2/translate`, traduce cadenas bajo demanda. Recibe como bearer token una clave de API del proyecto con el permiso **Runtime translation**, y un cuerpo con un objeto `requests` cuyas claves son tus propios IDs, cada uno con una cadena `source` y un `metadata` opcional (por ejemplo, una nota de `context`), además de `sourceLocale`, `targetLocale` y un objeto `metadata` de nivel superior (que puede estar vacío). La respuesta usa esos mismos IDs como claves. Basta con un pequeño método de Ruby:

```ruby title="app/services/gt_translate.rb"
require "net/http"
require "json"

# Traduce un hash de { field => text } con la API de tiempo de ejecución de General Translation.
# Devuelve todas las traducciones solicitadas o lanza una excepción antes de cualquier escritura en la base de datos.
def gt_translate(fields, from:, to:, context: nil)
  uri = URI("https://api.gtx.dev/v2/translate")
  requests = fields.to_h do |field, text|
    [field.to_s, { source: text, metadata: { dataFormat: "STRING", context: context }.compact }]
  end

  request = Net::HTTP::Post.new(uri)
  request["Authorization"] = "Bearer #{ENV.fetch("GT_API_KEY")}" # clave del proyecto con el permiso Runtime translation
  request["Content-Type"] = "application/json"
  request["gt-api-version"] = "2026-03-06.v1"
  request.body = { requests:, sourceLocale: from.to_s, targetLocale: to.to_s, metadata: {} }.to_json

  response = Net::HTTP.start(uri.host, uri.port, use_ssl: true,
                            open_timeout: 5, read_timeout: 30) { |http| http.request(request) }
  raise "Translation request failed (#{response.code})" unless response.is_a?(Net::HTTPSuccess)

  results = JSON.parse(response.body)
  requests.keys.to_h do |field|
    result = results.fetch(field)
    unless result["success"] == true && result["translation"].is_a?(String)
      raise "Translation incomplete for #{field}"
    end
    [field, result.fetch("translation")]
  end
end
```

Para hacer una traducción puntual de la publicación anterior, lee sus atributos en inglés y guarda el resultado completo en español:

```ruby
source = Mobility.with_locale(:en) do
  { title: post.title(fallback: false), body: post.body(fallback: false) }
end
translated = gt_translate(source,
                          from: :en, to: :es, context: "Blog post for an online shoe store")
Mobility.with_locale(:es) { post.update!(translated) }
```

La función auxiliar comprueba que cada campo solicitado tenga traducción antes de actualizar la publicación. Las validaciones habituales de tu modelo se siguen aplicando. (Consulta la [referencia del endpoint](/docs/platform/openapi/reference/translation/translate-content) para ver los campos de la solicitud y de la respuesta).

Aquí General Translation va más allá de una simple llamada de traducción automática: el endpoint traduce con el [glosario y los prompts personalizados](/docs/platform/dashboard/guides/defining-context-for-translations) de tu proyecto, de modo que los nombres de productos y el tono sean coherentes con el resto de tu producto. La nota de contexto le indica que el texto es para una tienda de zapatos, y la terminología compartida mantiene esas descripciones de productos alineadas con tu aplicación y tu sitio de marketing. Mantén la clave de API en el servidor. Para automatizar el proceso de forma continua, integra la traducción en tu flujo de trabajo de publicación de contenido actual y respeta los [límites de solicitudes](/docs/platform/openapi/overview#api-basics) de la API.

El ejemplo guarda los datos directamente en el modelo. Si tus editores aprueban el contenido antes de publicarlo, guarda el resultado mediante el mismo proceso de borrador y publicación que usas para el artículo de origen.

## Mobility vs. General Translation de un vistazo

| Característica                            | Mobility                                                   | General Translation                                                                                             |
| ----------------------------------------- | ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| Qué es                                    | Gema de Ruby para almacenar atributos de modelo traducidos | Plataforma de traducción con una API HTTP, una CLI, bibliotecas para JavaScript y Python, y un panel de control |
| Almacena traducciones en tu base de datos | Sí, con ocho backends de almacenamiento                    | Proporciona traducciones para esos mismos atributos de modelo                                                   |
| Genera traducciones                       | No                                                         | Sí, mediante `POST /v2/translate`                                                                               |
| Integración con Ruby                      | Atributos de modelo y accesores por configuración regional | API HTTP llamada desde Ruby                                                                                     |
| Terminología y tono coherentes            | Depende de tus traductores                                 | Glosario y prompts personalizados aplicados en cada solicitud                                                   |
| Costo                                     | Gratis, MIT                                                | [Según el uso](https://generaltranslation.com/pricing)                                                          |

## Cuándo basta con Mobility

Usa solo Mobility cuando tus traducciones ya las escriben personas: editores que introducen cada idioma en un formulario de administración, una agencia de traducción o contenido que debe traducirse a mano, como los textos legales. También basta si admites dos o tres idiomas y los registros cambian pocas veces. Añade General Translation cuando el contenido llegue más rápido de lo que se puede traducir manualmente (por ejemplo, anuncios de usuarios, artículos de soporte o un catálogo con miles de productos) y quieras que cada nuevo registro esté disponible en todos los idiomas en cuanto se guarde.

## Conclusiones clave

* Mobility almacena y recupera atributos traducidos de los modelos en ocho backends, con alternativas de respaldo y soporte para consultas. No genera traducciones.
* Una aplicación Rails llama al endpoint `POST /v2/translate` de General Translation y guarda los atributos traducidos a través de Mobility.
* General Translation aplica tu glosario, tus prompts personalizados y el contexto específico de cada contenido, sin que tengas que cambiar tus modelos ni tu flujo de trabajo de publicación actuales.

## Related questions

- [General Translation vs. Rails I18n: ¿necesitas ambos?](https://generaltranslation.com/es/kb/general-translation-vs-rails-i18n.mdx): Rails I18n busca mensajes y da formato a fechas y números. General Translation genera las traducciones, las mantiene al día a medida que cambia tu texto en inglés y ofrece a tu equipo un panel de control para revisarlas. Usa ambos para publicar catálogos de Rails traducidos en cada lanzamiento.
- [General Translation vs. i18n-tasks: ¿cuál deberías usar?](https://generaltranslation.com/es/kb/general-translation-vs-i18n-tasks.mdx): i18n-tasks es una gema de Ruby que detecta claves de Rails I18n faltantes y sin usar, ordena los archivos de configuración regional y puede completar las claves faltantes mediante Google Translate, DeepL, OpenAI, Yandex o watsonx. General Translation traduce archivos de configuración regional completos con tu glosario, tus prompts personalizados y la revisión en el panel de control. Cumplen funciones distintas, y muchos equipos pueden usar ambas.
- [Alternativas a Google Translate: General Translation vs. Google Translate](https://generaltranslation.com/es/kb/general-translation-vs-google-translate.mdx): Google Translate es una forma rápida de traducir textos puntuales, pero lanzar un producto en otro idioma también exige traducir cada cadena en su contexto, mantener una terminología coherente, gestionar correctamente las variables y los plurales, revisar las traducciones y contar con un proceso de lanzamiento. General Translation entiende el contexto de cada cadena en tu código y automatiza todo el flujo de trabajo de localización, desde el código hasta la revisión y cada lanzamiento.
- [General Translation vs. i18next, react-intl y next-intl: ¿qué biblioteca de i18n deberías usar?](https://generaltranslation.com/es/kb/general-translation-vs-i18n-libraries.mdx): Las bibliotecas de código abierto como i18next, react-intl y next-intl no traducen nada. Muestran las traducciones que tú proporcionas en un archivo de catálogo para cada idioma, escritas por ti, por tus traductores o por un servicio externo. Las bibliotecas de General Translation también son de código abierto y cumplen la misma función, pero además General Translation se encarga de traducir, usando tu código como contexto.
- [¿Por qué usar General Translation en lugar de un TMS (Smartling, Lokalise, Phrase, Crowdin o Transifex)?](https://generaltranslation.com/es/kb/general-translation-vs-tms.mdx): Un sistema de gestión de traducciones (TMS) como Smartling, Lokalise, Phrase, Crowdin o Transifex coordina a los traductores, pero los ingenieros siguen teniendo que extraer las cadenas, enviarlas, esperar las traducciones y volver a integrarlas en el producto. General Translation traduce el contenido de tu código junto con su contexto, incluye todos los idiomas en cada lanzamiento y funciona con bibliotecas de código abierto, sin dependencia de proveedor.

## Previous and next questions

- Previous question: [General Translation vs. Locize: ¿cuál deberías usar?](https://generaltranslation.com/es/kb/general-translation-vs-locize.mdx)
- Next question: [General Translation vs. nestjs-i18n: ¿cuál deberías usar?](https://generaltranslation.com/es/kb/general-translation-vs-nestjs-i18n.mdx)

## Sitemap

See the [Knowledge Base sitemap](https://generaltranslation.com/es/kb/sitemap.md) for every article.
