Как (и нужно ли) заполнять приложение rails исходными данными

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

Задав этот вопрос, мне кажется, что я должен использовать db: schema: load, а не запускать миграции, чтобы настроить свежие базы данных на новых машинах для разработки. К сожалению, это, похоже, не включает миграции, которые вставляют данные, а только те, которые настраивают таблицы, ключи и т. Д.

У меня вопрос, как лучше всего справиться с этой ситуацией:

  1. Есть ли способ заставить d: s: l включить миграции с вставкой данных?
  2. Должен ли я вообще не использовать миграции для вставки данных таким образом?
  3. Должен ли я вообще не заполнять базу данных данными заранее? Следует ли мне обновить код приложения, чтобы он корректно обрабатывал случай, когда нет пользователей, и позволял создать начальную учетную запись пользователя в реальном времени из приложения?
  4. Есть другие варианты? :)

person Luke Halliwell    schedule 15.09.2008    source источник


Ответы (13)


Попробуйте выполнить задание на грабли. Например:

  1. Создайте файл /lib/tasks/bootstrap.rake.
  2. В файле добавьте задачу для создания пользователя по умолчанию:

    namespace :bootstrap do
      desc "Add the default user"
      task :default_user => :environment do
        User.create( :name => 'default', :password => 'password' )
      end

      desc "Create the default comment"
      task :default_comment => :environment do
        Comment.create( :title => 'Title', :body => 'First post!' )
      end

      desc "Run all bootstrapping tasks"
      task :all => [:default_user, :default_comment]
    end
  1. Затем, когда вы настраиваете свое приложение в первый раз, вы можете выполнить rake db: migrate ИЛИ rake db: schema: load, а затем выполнить rake bootstrap: all.
person Aaron Wheeler    schedule 15.09.2008
comment
не работает, если / lib - это RO, например, если вы находитесь в среде общего хостинга. У вас есть решение, которое сработает в таком случае? - person cbrulak; 23.03.2010
comment
Я почти уверен, что он говорит о каталоге вашего приложения / lib. - person Azeem.Butt; 05.04.2010

Используйте db/seed.rb из каждого приложения Rails.

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

Заполнение исходных данных в базе данных должно производиться с помощью db/seed.rb файла.

Он работает как файл Ruby.

Чтобы создать и сохранить объект, вы можете сделать что-то вроде:

User.create(:username => "moot", :description => "king of /b/")

Когда у вас будет готов этот файл, вы можете сделать следующее

rake db:migrate

rake db:seed

Или за один шаг

rake db:setup

Ваша база данных должна быть заполнена любыми объектами, которые вы хотите создать в seed.rb.

person Jason Kim    schedule 13.02.2013
comment
db: seed сделал это за меня. - person Krishna Vedula; 27.09.2016

Я рекомендую вам не вставлять новые данные при миграции. Вместо этого изменяйте только существующие данные в миграциях.

Для вставки исходных данных рекомендую использовать YML. В каждом проекте Rails, который я настраиваю, я создаю каталог fixtures в каталоге DB. Затем я создаю файлы YML для исходных данных так же, как файлы YML используются для тестовых данных. Затем я добавляю новую задачу для загрузки данных из файлов YML.

lib / tasks / db.rake:

namespace :db do
  desc "This loads the development data."
  task :seed => :environment do
    require 'active_record/fixtures'
    Dir.glob(RAILS_ROOT + '/db/fixtures/*.yml').each do |file|
      base_name = File.basename(file, '.*')
      say "Loading #{base_name}..."
      Fixtures.create_fixtures('db/fixtures', base_name)
    end
  end

  desc "This drops the db, builds the db, and seeds the data."
  task :reseed => [:environment, 'db:reset', 'db:seed']
end

db / fixtures / users.yml:

test:
  customer_id: 1
  name: "Test Guy"
  email: "[email protected]"
  hashed_password: "656fc0b1c1d1681840816c68e1640f640c6ded12"
  salt: "188227600.754087929365988"
person Jay Stramel    schedule 15.09.2008

Это мое новое любимое решение, использующее самоцветы populator и faker:

http://railscasts.com/episodes/126-populating-a-database

person Community    schedule 16.09.2008

Попробуйте seed-fu плагин, который является довольно простым плагином, который позволяет вам заполнять данные (и изменять эти исходные данные в будущем), также позволит вам заполнить данные, специфичные для среды, и данные для всех сред.

person DEfusion    schedule 16.09.2008

Я думаю, что лучший вариант - номер 3, в основном потому, что в этом случае не будет пользователя по умолчанию, что является отличным способом сделать бесполезной хорошую безопасность.

person Vinko Vrsalovic    schedule 15.09.2008

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

Здесь есть две отдельные проблемы:

  1. Должен ли я предварительно заполнить базу данных моим специальным пользователем-администратором? Или приложение должно предоставлять способ настройки при первом использовании?
  2. Как предварительно заполнить базу данных данными? Обратите внимание, что это допустимый вопрос независимо от ответа на часть 1: существуют другие сценарии использования для предварительного заполнения, кроме пользователя с правами администратора.

Для (1) кажется, что настройка первого пользователя из самого приложения - это довольно большая дополнительная работа для функциональности, которая, по определению, почти никогда не используется. Однако он может быть немного более безопасным, поскольку заставляет пользователя устанавливать пароль по своему выбору. Лучшее решение находится между этими двумя крайностями: иметь скрипт (или задачу rake, или что-то еще) для настройки исходного пользователя. Затем сценарий может быть настроен на автоматическое заполнение пароля по умолчанию во время разработки и требование ввода пароля во время производственной установки / развертывания (если вы не хотите использовать пароль по умолчанию для администратора).

Похоже, что для (2) существует ряд хороших и правильных решений. Задача с рейком кажется хорошим способом, и есть несколько плагинов, которые сделают это еще проще. Просто просмотрите некоторые другие ответы, чтобы узнать подробности о них :)

person Luke Halliwell    schedule 16.09.2008

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

На вашей производственной машине:

script/console production

... тогда ...

User.create(:name => "Whoever", :password => "whichever")

Если вы генерируете этого исходного пользователя более одного раза, вы также можете добавить скрипт в RAILS_ROOT / script / и запустить его из командной строки на вашем производственном компьютере или с помощью задачи capistrano.

person Trevor Stow    schedule 15.09.2008

Эта задача Rake может быть предоставлена ​​плагином db-populate:

http://github.com/joshknowles/db-populate/tree/master

person pantulis    schedule 15.09.2008

Отличное сообщение в блоге по этому поводу: http://railspikes.com/2008/2/1/loading-seed-data

Я использовал предложения Джея о специальном наборе приспособлений, но быстро обнаружил, что создаю данные, которые невозможно было бы использовать напрямую с помощью моделей (неверсионные записи, когда я использовал actions_as_versioned)

person Kevin Davis    schedule 10.09.2010

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

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

person Matthias Winkelmann    schedule 15.09.2008

Для пользователей и групп вопрос о ранее существовавших пользователях следует определять с учетом потребностей приложения, а не непредвиденных обстоятельств программирования. Возможно, вашему приложению требуется администратор; затем заселите заранее. Или, возможно, нет - затем добавьте код, чтобы изящно запрашивать настройку пользователя во время запуска приложения.

Что касается более общего вопроса, очевидно, что многие приложения Rails могут выиграть от предварительно заполненной даты. Например, приложение для хранения адресов в США может также содержать все штаты и их сокращения. Я считаю, что в этих случаях миграции - ваш друг.

person NickR    schedule 15.09.2008

Некоторые ответы устарели. Начиная с Rails 2.3.4, в db/seed.rb есть простая функция под названием Seed:

#db/seed.rb
User.create( :name => 'default', :password => 'password' )
Comment.create( :title => 'Title', :body => 'First post!' )

Он предоставляет новую задачу rake, которую вы можете использовать после миграции для загрузки данных:

rake db:seed

Seed.rb - это классический файл Ruby, вы можете свободно использовать любую классическую структуру данных (массив, хэши и т. Д.) И итераторы для добавления ваших данных:

["bryan", "bill", "tom"].each do |name|
  User.create(:name => name, :password => "password")
end

Если вы хотите добавить данные с символами UTF-8 (очень часто во французском, испанском, немецком и т. Д.), Не забудьте добавить в начало файла:

# ruby encoding: utf-8

Этот Railscast - хорошее введение: http://railscasts.com/episodes/179-seed-data < / а>

person frenci    schedule 21.01.2014