Подтвердить что ты не робот

Как добавить новые данные семян в существующую базу данных рельсов

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

В большинстве советов используется seed.rb, однако я понимаю, что это выполняется только один раз, когда приложение изначально развертывается. Поскольку мы не хотим перестраивать тестовые и промежуточные базы данных так, чтобы мы могли добавить 1 строку справочных данных, есть ли другой способ добавить данные?

Я думаю об использовании миграции db, это правильный подход?

Спасибо

4b9b3361

Ответ 1

Создайте файл seed.rb, чтобы разрешить текущее создание и обновление данных. Вы не ограничены только запуском файла семени только один раз, и если вы считаете, что он используется только для первоначального развертывания, вы пропустите гибкость, которую он может предложить при настройке ссылочных данных.

Файл семян просто рубиновый, поэтому вы можете делать такие вещи, как:

user = User.find_or_initialize_by(email: '[email protected]')
user.name = 'Bob'
user.password = 'secret'
user.role = 'manager'
user.save!

Это создаст новые данные, если их не существует или обновит данные, если они найдут некоторые.

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

Я рекомендую использовать функцию bang save, чтобы исключить исключения в случае невозможности сохранения объекта. Это самый простой способ отладки семян.

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

Я не рекомендую использовать миграции для данных семян. Существует недостаток гибкости (как вы ориентируете данные семян только на одну среду, например), и нет реального способа создания повторно используемого набора данных, который может быть запущен в любое время для обновления конкретной среды. У вас также будет набор миграций, которые не имеют ссылки на вашу схему, и вам придется создавать новые миграции каждый раз, когда вы хотите генерировать новые или изменять текущие данные.

Ответ 2

Вы можете использовать миграцию, но это не самый безопасный вариант. Скажем, например, вы добавляете запись в таблицу через миграцию, а затем в будущем вы меняете эту схему таблиц. Когда вы где-нибудь будете устанавливать приложение, вы не сможете запустить rake db:migrate.

Семена всегда рекомендуются, потому что rake db:seed можно запускать на полностью перенесенной схеме.

Если это только для записи, перейдите к консоли рельсов.

Ответ 3

Лучше всего использовать метод idempotent, подобный этому в seed.rb, или другую задачу, вызванную seed.rb:

Contact.find_by_email("[email protected]") || Contact.create(email: "[email protected]", phone: "202-291-1970", created_by: "System")
# This saves you an update to the DB if the record already exists.

Или аналогично @nmott's:

Contact.find_or_initialize_by_email("[email protected]").update_attributes(phone: "202-291-1970", created_by: "System")
# this performs an update regardless, but it may be useful if you want to reset your data.

или используйте assign_attributes вместо update_attributes, если вы хотите назначить несколько атрибутов перед сохранением.

Ответ 4

Я использую файл seed для добавления экземпляров в новые или существующие таблицы все время. Мое решение прост. Я просто комментирую все остальные данные семени в файле db/seeds.rb, так что только новые исходные данные являются живым кодом. Затем запустите bin/rake db:seed.

Ответ 5

Я сделал что-то подобное в seed.rb

users_list = [
   {id: 1, name: "Diego", age: "25"},
   {id: 2, name: "Elano", age: "27"}
]

while !users_list.empty? do
  begin
    User.create(users_list)
  rescue
    users_list = users_list.drop(1) #removing the first if the id already exist.
  end
end

Если элемент в списке с указанным идентификатором уже существует, он вернет исключение, затем мы удалим этот элемент и попробуем его еще раз, пока массив users_list не будет пустым.

Таким образом, вам не нужно искать каждый объект перед его включением, но вы не сможете обновить уже вставленные значения, как в коде @nmott.

Ответ 6

Вместо изменения seeds.db, который вы, вероятно, захотите использовать для посева новых баз данных, вы можете создать настраиваемую задачу Rake (RailsCast # 66 Custom Rake Tasks).

Вы можете создать столько задач Rake, сколько захотите. Например, скажем, у вас есть два сервера, одна из которых работает в версии 1.0 вашего приложения, другая - с 1.1, и вы хотите обновить оба до 1.2. Затем вы можете создать lib/tasks/1-0-to-1-2.rake и lib/tasks`1-1-to-1-2.rake, так как вам может понадобиться другой код в зависимости от версии вашего приложения.