Каков наилучший способ заполнить базу данных в Rails? - PullRequest
76 голосов
/ 17 апреля 2009

У меня есть грабли, которые заполняют некоторые начальные данные в моем приложении rails. Например, страны, штаты, операторы мобильной связи и т. Д.

То, как я его сейчас настроил, это то, что у меня есть куча операторов create в файлах в / db / fixtures и одна задача rake, которая их обрабатывает. Например, одна модель у меня есть темы. У меня есть файл theme.rb в / db / fixtures, который выглядит следующим образом:

Theme.delete_all
Theme.create(:id => 1, :name=>'Lite', :background_color=>'0xC7FFD5', :title_text_color=>'0x222222',
                      :component_theme_color=>'0x001277', :carrier_select_color=>'0x7683FF', :label_text_color=>'0x000000',
                      :join_upper_gradient=>'0x6FAEFF', :join_lower_gradient=>'0x000000', :join_text_color=>'0xFFFFFF',
                      :cancel_link_color=>'0x001277', :border_color=>'0x888888', :carrier_text_color=>'0x000000', :public => true)

Theme.create(:id => 2, :name=>'Metallic', :background_color=>'0x000000', :title_text_color=>'0x7299FF',
                      :component_theme_color=>'0xDBF2FF', :carrier_select_color=>'0x000000', :label_text_color=>'0xDBF2FF',
                      :join_upper_gradient=>'0x2B25FF', :join_lower_gradient=>'0xBEFFAC', :join_text_color=>'0x000000',
                      :cancel_link_color=>'0xFF7C12', :border_color=>'0x000000', :carrier_text_color=>'0x000000', :public => true)

Theme.create(:id => 3, :name=>'Blues', :background_color=>'0x0060EC', :title_text_color=>'0x000374',
                      :component_theme_color=>'0x000374', :carrier_select_color=>'0x4357FF', :label_text_color=>'0x000000',
                      :join_upper_gradient=>'0x4357FF', :join_lower_gradient=>'0xffffff', :join_text_color=>'0x000000',
                      :cancel_link_color=>'0xffffff', :border_color=>'0x666666', :carrier_text_color=>'0x000000', :public => true)
puts "Success: Theme data loaded"

Идея в том, что я хочу установить несколько стандартных тем, чтобы пользователи могли начать с них. У меня проблема с этим методом.

Установка идентификатора не работает. Это означает, что если я решу добавить тему, давайте назовем ее «Red», то я просто хотел бы добавить инструкцию theme в этот файл фикстуры и вызвать задачу rake для повторного заполнения базы данных. Если я это сделаю, поскольку темы принадлежат другим объектам, и их идентификатор изменяется после этой повторной инициализации, все ссылки нарушаются.

Мой вопрос в первую очередь, это хороший способ обработать заполнение базы данных? В предыдущем посте это было рекомендовано мне.

Если так, как я могу жестко закодировать идентификаторы, и есть ли какие-либо недостатки в этом?

Если нет, каков наилучший способ заполнить базу данных?

Я буду очень признателен за длинные и продуманные ответы, включающие лучшие практики.

Ответы [ 7 ]

108 голосов
/ 15 января 2010

Обновление, так как эти ответы немного устарели (хотя некоторые все еще применяются).

Добавлена ​​простая функция в рельсах 2.3.4, дБ / seed.rb

Предоставляет новое рейк-задание

rake db:seed

Хорошо подходит для заполнения общих статических записей, таких как состояния, страны и т. Д. *

http://railscasts.com/episodes/179-seed-data

* Обратите внимание, что вы можете использовать приборы, если вы уже создали их, чтобы также заполнить задачу db: seed, поместив в свой файл seed.rb (из серии railscast) следующее:

require 'active_record/fixtures'
Fixtures.create_fixtures("#{Rails.root}/test/fixtures", "operating_systems")

Для Rails 3.x используйте константу 'Fixtures' вместо ActiveRecord :: Fixtures

require 'active_record/fixtures'
ActiveRecord::Fixtures.create_fixtures("#{Rails.root}/test/fixtures", "fixtures_file_name")
26 голосов
/ 04 апреля 2011

Обычно требуется 2 типа данных для посева.

  • Основные данные , на которые может опираться ядро ​​вашего приложения. Я называю это общими семенами.
  • Экологические данные , например, для разработки приложения полезно иметь группу данных в известном состоянии, которую мы можем использовать для локальной работы над приложением (ответ Factory Girl выше охватывает этот вид данных).

По своему опыту я всегда сталкивался с необходимостью этих двух типов данных. Поэтому я собрал небольшой драгоценный камень, который расширяет семена Rails и позволяет вам добавить несколько общих файлов с семенами в db / seed / и любые данные о семенах окружающей среды в db / seed / ENV, например db / seed / development.

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

rake db:setup

Приспособления хрупки и ненадежны в обслуживании, как и обычные дампы sql.

25 голосов
/ 17 апреля 2009

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

Factory.define :theme do |t|
  t.background_color '0x000000'
  t.title_text_color '0x000000',
  t.component_theme_color '0x000000'
  t.carrier_select_color '0x000000'
  t.label_text_color '0x000000',
  t.join_upper_gradient '0x000000'
  t.join_lower_gradient '0x000000'
  t.join_text_color '0x000000',
  t.cancel_link_color '0x000000'
  t.border_color '0x000000'
  t.carrier_text_color '0x000000'
  t.public true
end

Factory(:theme, :id => 1, :name => "Lite", :background_color => '0xC7FFD5')
Factory(:theme, :id => 2, :name => "Metallic", :background_color => '0xC7FFD5')
Factory(:theme, :id => 3, :name => "Blues", :background_color => '0x0060EC')

При использовании с фейкером он может очень быстро заполнить базу данных ассоциациями без необходимости связываться с Fixtures (блин).

У меня есть такой код в граблях.

100.times do
    Factory(:company, :address => Factory(:address), :employees => [Factory(:employee)])
end
21 голосов
/ 26 ноября 2013

Использование seeds.rb файла или FactoryBot - это замечательно, но они соответственно хороши для фиксированных структур данных и тестирования.

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

rake db:seed                    # Load the seed data from db/seeds.rb, db/seeds/*.seeds.rb and db/seeds/ENVIRONMENT/*.seeds.rb. ENVIRONMENT is the current environment in Rails.env.
rake db:seed:bar                # Load the seed data from db/seeds/bar.seeds.rb
rake db:seed:common             # Load the seed data from db/seeds.rb and db/seeds/*.seeds.rb.
rake db:seed:development        # Load the seed data from db/seeds.rb, db/seeds/*.seeds.rb and db/seeds/development/*.seeds.rb.
rake db:seed:development:users  # Load the seed data from db/seeds/development/users.seeds.rb
rake db:seed:foo                # Load the seed data from db/seeds/foo.seeds.rb
rake db:seed:original           # Load the seed data from db/seeds.rb
1 голос
/ 05 мая 2014

В Rails есть встроенный способ заполнения данных, как объяснено здесь .

Другой способ - использовать драгоценный камень для более продвинутого или простого посева, например: seedbank .

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

Добавление актуального ответа, так как этот ответ был первым в Google.

0 голосов
/ 17 апреля 2009

Добавьте его в миграцию базы данных, чтобы каждый получил его при обновлении. Обрабатывайте всю свою логику в коде ruby ​​/ rails, чтобы вам никогда не приходилось связываться с явными настройками идентификатора.

0 голосов
/ 17 апреля 2009

Лучший способ - использовать светильники.

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

...