Каков наилучший способ засевать базу данных в Rails?
У меня есть задача rake, которая заполняет некоторые исходные данные в моем приложении rails. Например, страны, штаты, мобильные операторы и т.д.
Как я его настроил сейчас, у меня есть куча создания операторов в файлах в /db/fixtures и задача грабли, которая их обрабатывает. Например, у одной модели есть темы. У меня есть файл 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", тогда я просто хотел бы добавить оператор темы в этот файл привязки и вызвать задачу rake для повторной загрузки базы данных. Если я это сделаю, потому что темы относятся к другим объектам и их идентификатор изменяется при этой повторной инициализации, все ссылки нарушаются.
Мой вопрос в первую очередь, это хороший способ справиться с посевом базы данных? В предыдущем посте мне это рекомендовалось.
Если да, то как я могу жестко закодировать идентификаторы и есть ли какие-то недостатки?
Если нет, каков наилучший способ засеять базу данных?
Я буду по-настоящему ценить длительные и продуманные ответы, которые включают лучшие практики.
Ответы
Ответ 1
Обновление, так как эти ответы немного устарели (хотя некоторые из них все еще применяются).
Простая функция, добавленная в rails 2.3.4, db/seeds.rb
Предоставляет новую команду rake
rake db:seed
Хорошо для заполнения обычных статических записей, таких как состояния, страны и т.д.
http://railscasts.com/episodes/179-seed-data
* Обратите внимание, что вы можете использовать приборы, если вы уже создали их, чтобы также заполнить задачу db: seed, поместив следующее в файл seeds.rb(из эпизода railscast):
require 'active_record/fixtures'
Fixtures.create_fixtures("#{Rails.root}/test/fixtures", "operating_systems")
Для Rails 3.x используйте 'ActiveRecord:: Fixtures' вместо константы Fixtures
require 'active_record/fixtures'
ActiveRecord::Fixtures.create_fixtures("#{Rails.root}/test/fixtures", "fixtures_file_name")
Ответ 2
factory_girl звучит так, будто он будет делать то, что вы пытаетесь достичь. Вы можете определить все общие атрибуты в определении по умолчанию и затем переопределить их во время создания. Вы также можете передать идентификатор factory:
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')
При использовании с faker он может быстро заполнить базу данных ассоциациями без необходимости общаться с Fixtures (yuck).
У меня есть код, подобный этому в задаче грабли.
100.times do
Factory(:company, :address => Factory(:address), :employees => [Factory(:employee)])
end
Ответ 3
Обычно требуется 2 типа данных семян.
- Основные данные, на которые может положиться ядро вашего приложения. Я называю это обычными семенами.
- Экологические данные, например, для разработки приложения полезно иметь кучу данных в известном состоянии, которые мы можем использовать для работы в приложении локально (ответ Factory Girl выше охватывает такие данные).
По моему опыту, я всегда сталкивался с необходимостью этих двух типов данных. Поэтому я собрал небольшой камень, который расширяет семплы Rails и позволяет добавлять несколько общих семян файлы под db/seed/и любые данные о семенах окружающей среды под db/seed/ENV, например db/seed/development.
Я нашел, что такого подхода достаточно, чтобы дать мои данные о семени некоторую структуру и дает мне возможность настроить мою среду разработки или промежуточной стадии в известном состоянии, просто выполнив:
rake db:setup
Светильники хрупкие и непрозрачные для поддержания, как и обычные свалки sql.
Ответ 4
Использование файла seeds.rb
или FactoryGirl
отлично, но они отлично подходят для фиксированных структур данных и тестирования.
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
Ответ 5
Вместо использования явных созданий используйте файлы YAML.
С помощью простого синтаксиса вы можете заполнить все значения объекта.
На самом деле, если вы знаете что-нибудь о тестировании рельсов, это стандартный способ засеять тестовую базу данных.
Проверьте эти страницы:
http://railspikes.com/2008/2/1/loading-seed-data
http://quotedprintable.com/2007/11/16/seed-data-in-rails
Ответ 6
Добавьте его в миграцию базы данных, таким образом, каждый получает его по мере обновления. Управляйте всей своей логикой в коде ruby /rails, поэтому вам никогда не придется возиться с явными настройками идентификатора.
Ответ 7
Rails имеет встроенный способ генерации данных, как описано здесь.
Другой способ - использовать драгоценный камень для более продвинутого или простого посева, например: seedbank.
Основное преимущество этого драгоценного камня и причина, по которой я его использую, заключается в том, что он имеет расширенные возможности, такие как зависимости загрузки данных и данные о семенной среде.
Добавление актуального ответа, поскольку этот ответ был первым в google.
Ответ 8
Лучший способ - использовать светильники.
Примечание. Имейте в виду, что светильники делают прямые вставки и не используют вашу модель, поэтому, если у вас есть обратные вызовы, которые заполняют данные, вам нужно найти обходной путь.