# General Translation Knowledge Base: General Translation или Mobility: что выбрать?
URL: https://generaltranslation.com/ru/kb/general-translation-vs-mobility.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Mobility хранит переведённые атрибуты моделей в вашей базе данных. General Translation создаёт эти переводы через свой API с учётом вашего Glossary и пользовательских промптов. Используйте оба инструмента, чтобы переводить карточки товаров, публикации и другой контент из базы данных, не отказываясь от своих моделей Rails.
Category: Интернационализация
Last updated: 2026-10-16
Authors: Kevin Wu, Jackie Chen
Published: 2026-10-16

Mobility — это Ruby-гем для перевода данных в базе данных: вы объявляете `translates :title` в модели, и `post.title` возвращает заголовок в текущей локали, считывая его из выбранного вами бэкенда хранения. Гем хранит и извлекает переводы, а вот создавать их должны ваши редакторы, переводчики или внешний сервис. General Translation поставляет переводы через свой HTTP API. Mobility сохраняет переведённые атрибуты в уже существующей базе данных, так что с ними работают те же запросы и методы моделей, что и сейчас.

## Сильные стороны Mobility

* **Выбор способа хранения.** Бэкенд по умолчанию `key_value` [хранит все переводы в двух общих таблицах](https://github.com/shioyama/mobility/wiki/KeyValue-Backend) (одна для строк, другая для текста). Бэкенд `table` использует отдельную таблицу переводов для каждой модели (подход Globalize), `column` — столбцы с суффиксами, например `title_en` и `title_es`, `serialized` хранит переводы в одном текстовом столбце, а в PostgreSQL бэкенды `json`, `jsonb`, `hstore` и `container` (один столбец jsonb на модель) хранят их нативно. Можно также написать собственный бэкенд.
* **Единый API для всех бэкендов.** Чтение и запись выполняются для `I18n.locale`, а плагины (резервные варианты, методы доступа для конкретной локали вроде `post.title_es`, отслеживание изменений, кэширование и проверки наличия) [работают одинаково, какой бы бэкенд вы ни выбрали](https://github.com/shioyama/mobility#backends).
* **Запросы.** [`Post.i18n.where(title: "...")`](https://github.com/shioyama/mobility#querying) строит JOIN-ы для текущей локали, так что искать по переведённым атрибутам можно, не зная, как они хранятся.
* **Поддержка ORM.** Библиотека [работает с Active Record 7.0 и новее, а также с Sequel](https://github.com/shioyama/mobility#installation), а в её вики есть руководство по миграции с Globalize.
* **Бесплатно.** Распространяется по лицензии MIT; [текущий релиз — 1.3.2](https://rubygems.org/gems/mobility).

## Что Mobility оставляет на ваше усмотрение

Вот пост с заголовком и текстом на английском языке. Он использует бэкенд `key_value` на SQLite, а резервный переход с испанского на английский настроен только для заголовка:

```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" (на английском, через резервную локаль)
I18n.with_locale(:es) { post.body }  # => nil
I18n.with_locale(:ja) { post.title } # => nil
```

Для слоя хранения это правильное поведение: Mobility сохранил английские значения, а все остальные локали остаются пустыми, пока кто-нибудь их не заполнит. Если задан резервный язык, испаноязычные читатели увидят английский текст, если нет — ничего. Для контента, который меняется каждый день, — карточек товаров, статей или страниц справки — кому-то придётся переводить каждую новую или отредактированную запись на каждый язык и сохранять её в нужной локали.

## Заполнение атрибутов Mobility с помощью General Translation

Эндпоинт перевода во время выполнения General Translation, `POST https://api.gtx.dev/v2/translate`, переводит строки по запросу. В качестве bearer-токена он принимает ключ API проекта с разрешением **Runtime translation**, а в теле запроса — объект `requests`, ключами которого служат ваши собственные идентификаторы. Каждый элемент содержит строку `source` и необязательное поле `metadata`, например с заметкой `context`. Кроме того, в теле передаются `sourceLocale`, `targetLocale` и объект `metadata` верхнего уровня (он может быть пустым). Ответ использует те же идентификаторы в качестве ключей. Для работы с ним достаточно небольшого метода на Ruby:

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

# Переводит хеш вида { field => text } через API перевода во время выполнения General Translation.
# Возвращает все запрошенные переводы либо выбрасывает исключение до какой-либо записи в базу данных.
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")}" # ключ проекта с разрешением 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
```

Чтобы разово перевести приведённую выше запись, прочитайте её атрибуты на английском и сохраните полный результат на испанском:

```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) }
```

Вспомогательная функция проверяет, что для каждого запрошенного поля есть перевод, и только после этого обновляет запись. Стандартные валидации вашей модели при этом продолжают работать. (Поля запроса и ответа описаны в [справочнике по эндпоинту](/docs/platform/openapi/reference/translation/translate-content).)

General Translation делает здесь больше, чем простой вызов машинного перевода: эндпоинт переводит текст с учётом [Glossary и пользовательских промптов](/docs/platform/dashboard/guides/defining-context-for-translations) вашего проекта, поэтому названия продуктов и тон согласуются с остальным продуктом. Заметка с контекстом сообщает, что текст предназначен для обувного магазина, а общая терминология обеспечивает единообразие описаний товаров в приложении и на маркетинговом сайте. Храните ключ API на сервере. Для постоянной автоматизации встройте перевод в существующий рабочий процесс публикации контента и соблюдайте [ограничения частоты запросов](/docs/platform/openapi/overview#api-basics) API.

В примере результат сохраняется прямо в модель. Если ваши редакторы утверждают контент перед публикацией, сохраняйте результат через тот же процесс черновиков и публикации, что и исходную статью.

## Mobility и General Translation: краткое сравнение

| Возможность                         | Mobility                                             | General Translation                                                                           |
| ----------------------------------- | ---------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| Что это                             | Ruby-гем для хранения переведённых атрибутов моделей | Платформа перевода с HTTP API, CLI, библиотеками для JavaScript и Python и панелью управления |
| Хранит переводы в вашей базе данных | Да, поддерживает восемь бэкендов хранения            | Передаёт переводы в те же атрибуты моделей                                                    |
| Создаёт переводы                    | Нет                                                  | Да, через `POST /v2/translate`                                                                |
| Интеграция с Ruby                   | Атрибуты моделей и методы доступа по локалям         | HTTP API, вызываемый из Ruby                                                                  |
| Единообразие терминологии и тона    | Зависит от ваших переводчиков                        | Glossary и пользовательские промпты применяются к каждому запросу                             |
| Стоимость                           | Бесплатно, лицензия MIT                              | [Оплата по факту использования](https://generaltranslation.com/pricing)                       |

## Когда достаточно одной Mobility

Обходитесь одной Mobility, если переводы у вас уже делают люди: редакторы, которые заполняют каждый язык в форме админки, бюро переводов — или если речь идёт о контенте вроде юридических текстов, которые нужно переводить вручную. Её хватит и в том случае, если вы поддерживаете два-три языка, а записи меняются редко. Подключайте General Translation, когда контент появляется быстрее, чем люди успевают его переводить (например, пользовательские объявления, статьи службы поддержки или каталог с тысячами товаров), и вам нужно, чтобы каждая новая запись становилась доступна на всех языках сразу после сохранения.

## Ключевые выводы

* Mobility хранит и извлекает переведённые атрибуты моделей в восьми бэкендах и поддерживает резервные варианты и запросы. Сам Mobility переводы не создаёт.
* Приложение на Rails вызывает эндпоинт General Translation `POST /v2/translate` и сохраняет переведённые атрибуты через Mobility.
* General Translation применяет ваш Glossary, пользовательские промпты и контекст конкретного контента, при этом ваши существующие модели и рабочий процесс публикации остаются без изменений.

## Related questions

- [General Translation и Rails I18n: нужны ли оба?](https://generaltranslation.com/ru/kb/general-translation-vs-rails-i18n.mdx): Rails I18n находит сообщения и форматирует даты и числа. General Translation создаёт переводы, поддерживает их в актуальном состоянии по мере изменения английского текста и предоставляет вашей команде панель управления для проверки. Используйте оба инструмента, чтобы выпускать переведённые каталоги Rails с каждым релизом.
- [General Translation или i18n-tasks: что выбрать?](https://generaltranslation.com/ru/kb/general-translation-vs-i18n-tasks.mdx): i18n-tasks — это Ruby-gem, который находит отсутствующие и неиспользуемые ключи Rails I18N, наводит порядок в файлах локалей и умеет заполнять недостающие ключи с помощью Google Translate, DeepL, OpenAI, Yandex или watsonx. General Translation переводит файлы локалей целиком с учётом вашего Glossary и пользовательских промптов, а результат можно проверить в панели управления. Эти инструменты решают разные задачи, и многим командам пригодятся оба.
- [Альтернативы Google Translate: General Translation и Google Translate](https://generaltranslation.com/ru/kb/general-translation-vs-google-translate.mdx): Google Translate — быстрый способ перевести разовый текст, но чтобы выпустить продукт на другом языке, нужно переводить каждую строку с учётом контекста, соблюдать единую терминологию, правильно обрабатывать переменные и формы множественного числа, проводить ревью и выстроить процесс релизов. General Translation понимает контекст каждой строки в вашем коде и автоматизирует весь рабочий процесс локализации — от кода до ревью и каждого релиза.
- [General Translation против i18next, react-intl и next-intl: какую библиотеку интернационализации выбрать?](https://generaltranslation.com/ru/kb/general-translation-vs-i18n-libraries.mdx): Библиотеки с открытым исходным кодом, такие как i18next, react-intl и next-intl, ничего не переводят. Они лишь отображают переводы, которые вы сами помещаете в файл каталога для каждого языка, — их пишете вы, ваши переводчики или сторонний сервис. Библиотеки General Translation тоже имеют открытый исходный код и делают то же самое, но General Translation ещё и выполняет перевод, используя ваш код как контекст.
- [Почему стоит выбрать General Translation вместо TMS (Smartling, Lokalise, Phrase, Crowdin или Transifex)?](https://generaltranslation.com/ru/kb/general-translation-vs-tms.mdx): Система управления переводами (TMS), например Smartling, Lokalise, Phrase, Crowdin или Transifex, координирует работу переводчиков, но инженерам всё равно приходится извлекать строки, отправлять их на перевод, ждать результатов и встраивать переводы обратно в продукт. General Translation переводит контент прямо в вашем коде с учётом контекста, выпускает все языки с каждым релизом и работает на библиотеках с открытым исходным кодом без привязки к поставщику.

## Previous and next questions

- Previous question: [General Translation или Locize: что выбрать?](https://generaltranslation.com/ru/kb/general-translation-vs-locize.mdx)
- Next question: [General Translation или nestjs-i18n: что выбрать?](https://generaltranslation.com/ru/kb/general-translation-vs-nestjs-i18n.mdx)

## Sitemap

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