Rails - Как использовать массовый импорт с текстом действия? - PullRequest
0 голосов
/ 06 апреля 2020

Я создаю приложение rails 6 и застрял в проблеме.

Допустим, у меня есть таблица задач, которая имеет 3 поля:

  • id
  • состояние
  • описание

Поле описания фактически является полем rich_text благодаря ActionText.

Моя проблема заключается в том, что у меня есть файл CSV, состоящий из 3 столбцы (id, состояние, описание) и, во время инициализации приложения, я хочу заполнить базу данных им, используя массовый импорт.

Обычно, если описание было обычным столбцом, я делал бы что-то вроде этого :

Task.insert_all(
 # My csv converted in array of hashes [{state: YY, description: ZZZZZZZ}]
)

Но поскольку описание на самом деле не является атрибутом задач таблицы, оно не будет работать. Как я могу по-прежнему использовать массовый импорт для импорта большого набора данных, но все еще использовать поля action_text?

Сейчас я вынужден использовать вставки «одна за другой», что занимает очень много времени!

Спасибо за любые выводы, которые вы можете принести.

1 Ответ

1 голос
/ 06 апреля 2020

Я думаю, что самый простой способ сделать это, разделив ваш ввод следующим образом:

# Tasks
tasks = { id: XX, state: YY, ... }

# Descriptions
descriptions = { record_type: 'Task', record_id: XX, name: 'description', body: 'Actual body' }

Тогда вы можете сделать что-то вроде этого:

Task.insert_all(tasks)
ActionText::RichText.insert_all(descriptions)

Это то, что вы ищете?

============================================== ===============

Обновление:

Просто чтобы уточнить, как это работает, нам нужно понять, что модель RichText работает как любая другая модель в Rails, но сериализуя информацию, как показано здесь: https://github.com/rails/rails/blob/master/actiontext/app/models/action_text/rich_text.rb#L11

Чтобы увидеть, что действительно извлекается из базы данных, мы можем использовать помощник *field*_before_type_cast. Например:

descriptions = [ { record_type: 'Task', record_id: XX, name: 'description', body: '<p>EXAMPLE</p>' } ]
ActionText::RichText.insert_all(descriptions)

ActionText::RichText.last.body => <ActionText::Content....>
ActionText::RichText.last.body_before_type_cast => '<p>EXAMPLE</p>'

Также имейте в виду, что в каждой записи может быть один форматированный текст (это 1 - N полиморфная c ассоциация). Таким образом, если вы попытаетесь вставить вторую задачу description для вашей задачи, она не будет работать

...