Как обновить столбец json в Rails? - PullRequest
2 голосов
/ 27 октября 2019

В моей таблице Categories есть столбец json, и я хочу обновить каждую запись категории переводом из файла json. Я создал файл json таким образом, чтобы он содержал массив категорий, а каждая категория имела имя и перевод, например:

{
  "categories": [
    {
        "name": "starter",
        "message": "Abs/Анти блокираща система (система против боксуване)"
    },
    {
        "name": "alternator",
        "message": "Алтернатор"
    }
    ...
  ]
}

Я хочу, чтобы каждая запись категории обновлялась с помощью языкового ключа, а такжеперевод из файла, вот так:

{ bg: 'translation from file' }

У меня есть этот код

file = File.read('app/services/translations/files/bg.json')
data = JSON.parse(file)
language = File.basename(file, '.json')
Translations::CategoriesMigrator.call(file: data, language: language)

module Translations
  class CategoriesMigrator < Service
    def initialize(category_repo: Category)
      @category_repo = category_repo
    end

    def call(file:, language:)
      file['categories'].each do |category|
        found_category = @category_repo.find_by(name: category['name'])
        found_category.translated_categories[language] = category['message']
        found_category.save
      end
    end
  end
end

Прямо сейчас у меня все категории в одной записи категории,Что я делаю не так?

Обновление

Моя миграция БД выглядит так:

class AddTranslatedCategoriesToCategories < ActiveRecord::Migration[5.1]
  def change
    add_column :categories, :translated_categories, :jsonb, null: false, default: {}
    add_index :categories, :translated_categories, using: :gin
  end
end

1 Ответ

3 голосов
/ 27 октября 2019

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

Этот случай определенно поздний, так как базовая структура не является динамической. Чтобы отслеживать переводы, нам просто нужно знать предмет, язык и перевод.

class Category
  has_many :category_translations
end

# rails g model category_translation category:belongs_to locale:string text:string
class CategoryTranslation
  belongs_to :category
end

Вы можете добавить составной индекс для category_id и locale для обеспечения уникальности.

См .:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...