Rails에서 데이터베이스를 시드하는 가장 좋은 방법은 무엇입니까?


82

레일스 앱에 초기 데이터를 채우는 레이크 작업이 있습니다. 예 : 국가, 주, 이동 통신사 등

지금 설정 한 방법은 / db / fixtures의 파일에 많은 create 문과이를 처리하는 레이크 작업이 있다는 것입니다. 예를 들어, 제가 가지고있는 한 가지 모델은 테마입니다. 다음과 같은 / db / fixtures에 theme.rb 파일이 있습니다.

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"

여기서 아이디어는 사용자가 시작할 수 있도록 몇 가지 스톡 테마를 설치하려는 것입니다. 이 방법에 문제가 있습니다.

ID 설정이 작동하지 않습니다. 즉, 테마를 추가하기로 결정한 경우 'Red'라고 부르겠습니다. 그러면이 조명기 파일에 테마 문을 추가하고 rake 작업을 호출하여 데이터베이스를 다시 시드하기 만하면됩니다. 그렇게하면 테마가 다른 개체에 속하고 다시 초기화 할 때 해당 ID가 변경되므로 모든 링크가 끊어집니다.

내 질문은 우선 데이터베이스 시드를 처리하는 좋은 방법입니까? 이전 게시물에서 이것은 나에게 권장되었습니다.

그렇다면 ID를 어떻게 하드 코딩 할 수 있습니까? 그에 대한 단점이 있습니까?

그렇지 않은 경우 데이터베이스를 시드하는 가장 좋은 방법은 무엇입니까?

모범 사례를 포함하는 오랜 답변에 대해 진심으로 감사드립니다.

답변:


113

이 답변은 약간 구식이므로 업데이트 중입니다 (일부는 여전히 적용됨).

rails 2.3.4, db / seeds.rb에 추가 된 간단한 기능

새로운 레이크 작업 제공

rake db:seed

주, 국가 등과 같은 일반적인 정적 레코드를 채우는 데 적합합니다.

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

* (railscast 에피소드에서) seed.rb 파일에 다음을 넣어 db : seed 작업을 채우기 위해 이미 만든 조명기를 사용할 수 있습니다.

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")

28

일반적으로 두 가지 유형의 시드 데이터가 필요합니다.

  • 애플리케이션의 핵심이 의존 할 수있는 기본 데이터 입니다. 나는 이것을 일반적인 씨앗이라고 부릅니다.
  • 환경 데이터 , 예를 들어 앱을 개발하려면 로컬에서 앱 작업에 사용할 수있는 알려진 상태의 데이터를 보유하는 것이 유용합니다 (위의 Factory Girl 답변은 이러한 종류의 데이터를 다룹니다).

제 경험상 저는 항상이 두 가지 유형의 데이터가 필요하다는 것을 알게되었습니다. 그래서 Rails의 시드를 확장 하고 db / seeds / 아래에 여러 개의 공통 시드 파일을 추가하고 db / seeds / ENV 아래에 환경 시드 데이터 (예 : db / seeds / development)를 추가 할 수 있는 작은 보석을 모았 습니다 .

이 접근 방식은 내 시드 데이터에 구조를 제공하고 다음을 실행하여 알려진 상태에서 개발 또는 스테이징 환경을 설정할 수있는 권한을 제공하기에 충분하다는 것을 알았습니다.

rake db:setup

고정 장치는 일반 SQL 덤프와 마찬가지로 유지 관리가 취약하고 결함이 있습니다.


저는 "시스템 데이터"와 "런타임 데이터"라는 용어를 사용하여 코드가 기존 데이터와 사용자 데이터에 의존하는 것을 설명합니다. 때때로 그들 사이의 경계가 흐릿합니다.
Tim Abell

27

factory_bot 은 달성하려는 작업을 수행하는 것처럼 들립니다. 기본 정의에서 모든 공통 속성을 정의한 다음 생성시 재정의 할 수 있습니다. 공장에 ID를 전달할 수도 있습니다.

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

11
FactoryGirl은 실제로 픽스쳐 대신 테스트를위한 것이지만, 프로덕션에 물건을로드하는 데에도 사용할 수 있습니다. 모든 기본 데이터를로드하려면 db : migrate가 전제 조건으로있는 레이크 태스크를 사용하십시오. 레이크 작업이 기존 데이터의 복사본을 만들지 않을만큼 충분히 지능적으로 만들어야 할 수도 있습니다.
Bob Aman

2
시드에 FactoryGirl을 사용하는 것은 권장되지 않습니다 . 이 게시물을 확인하십시오 .
blackbiron

26

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

Rails에는 여기에 설명 된대로 데이터를 시드하는 방식이 내장되어 있습니다 .

또 다른 방법은 seedbank 와 같이 더 고급 또는 쉬운 시딩을 위해 gem을 사용하는 것 입니다.

이 gem의 주요 장점과 제가 사용하는 이유는 데이터 로딩 종속성 및 환경 별 시드 데이터와 같은 고급 기능이 있다는 것입니다.

이 답변이 Google에서 처음 이었으므로 최신 답변을 추가하십시오.


-3

가장 좋은 방법은 조명기를 사용하는 것입니다.

참고 : 조명기는 직접 삽입을 수행하고 모델을 사용하지 않으므로 데이터를 채우는 콜백이있는 경우 해결 방법을 찾아야합니다.


-4

데이터베이스 마이그레이션에 추가하면 모든 사용자가 업데이트 할 때 얻을 수 있습니다. ruby / rails 코드에서 모든 로직을 처리하므로 명시적인 ID 설정을 엉망으로 만들 필요가 없습니다.


초기 데이터를 변경해야하는 경우 마이그레이션을 사용할 때 일이 지저분해질 수 있습니다. 두 번째 의견은 정말 의미가 없습니다. 외래 키를 통한 링크가 파괴됩니다
Tony

c = Category.create (stuff) p = Post.create (stuff) p.category = c 명시 적으로 ID를 설정할 필요가 없습니다. 초기 데이터를 변경하는 경우 새 마이그레이션을 생성하기 만하면됩니다. 아주 쉽습니다.
Matt Rogish 2009

즉, 객체가 생성 될 때 연관이 만들어 질 수 있다고 가정합니다. 여기에 내가 당신의 논리가 실패했다고 믿는 예가 있습니다 ... 내가 틀렸다면 나를 고쳐주세요. 나는 템플릿 테마로 DB를 시드합니다. user id = 1은 템플릿 id = 2이고 테마 id = 4를 만듭니다. 이 시점에서 레코드는 다음과 같이 db에 있습니다. template : id = 2, user_id = 1, theme_id = 4. 이제 db를 다시 초기화하면 테마 id = 4는 이제 테마 id = 10입니다. 그러면 사용자의 템플릿이 잘못 테마가 지정됩니다
Tony

"재 초기화"가 의미하는 바에 따라 다릅니다. 0에서 시작하면 Rails는 모든 연결을 자동으로 처리합니다. ID 값을 하드 코딩하는 경우 (나쁘다 !!!), 그렇습니다.
Matt Rogish 2009

네 요점을보기 시작했지만이 시나리오를 직접 실행해야합니다. 국가 조회 테이블로 데이터베이스를 시드합니다. 미국 => 국가 ID = 1. 그런 다음 사용자가 미국에있는 레스토랑을 만듭니다. 레스토랑 데이터베이스 행에는 country_id = 1이 있습니다. 이것은 매우 일반적입니다. 그렇죠? 나중에 더 많은 국가를 추가하기로 결정했습니다 .DB를 깨끗하게 지우고 국가 조회 테이블을 다시 채우면 ID가 동일하지 않으면 레스토랑 국가가 더 이상 정확하지 않습니다. 어떻게 처리합니까?
Tony
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.