¿Cuál es la mejor manera de sembrar una base de datos en Rails?


Tengo una tarea rake que rellena algunos datos iniciales en mi aplicación rails. Por ejemplo, países, estados, operadores de telefonía móvil, etc.

La forma en que lo tengo configurado ahora, es que tengo un montón de instrucciones create en archivos en /db/fixtures y una tarea rake que los procesa. Por ejemplo, un modelo que tengo es themes. Tengo un tema.archivo rb en/db / fixtures que se ve así:

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"

La idea aquí es que quiero instalar algunos temas de stock para que los usuarios comiencen. Tengo un problema con este método.

Establecer el ID no funciona. Esto significa que si decido agregar un tema, llamémoslo 'Rojo', entonces simplemente me gustaría agregar la declaración de tema a este archivo de accesorio y llamar a la tarea rake para volver a sembrar la base de datos. Si hago eso, debido a que los temas pertenecen a otros objetos y su id cambia en esta reinicialización, todos los enlaces se rompen.

Mi pregunta es, en primer lugar, ¿es esta una buena manera de manejar la siembra de una base de datos? En un post anterior, esto fue recomendado a mí.

Si es así, ¿cómo puedo codificar los IDs, y hay algún inconveniente en eso?

Si no, ¿cuál es la mejor manera de sembrar la base de datos?

Realmente apreciaré las respuestas largas y pensadas que incorporan las mejores prácticas.

Author: Nakilon, 2009-04-17

8 answers

Actualización ya que estas respuestas están un poco desactualizadas (aunque algunas todavía se aplican).

Característica sencilla añadida en rails 2.3.4, db/seeds.rb

Proporciona una nueva tarea de rake

rake db:seed

Bueno para rellenar registros estáticos comunes como estados, países, etc...

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

* Tenga en cuenta que puede usar accesorios si ya los había creado para rellenar también con la tarea db: seed poniendo lo siguiente en su semillas.archivo rb (del episodio railscast):

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

Para los carriles 3.x use' ActiveRecord::Fixtures 'en lugar de' Fixtures ' constant

require 'active_record/fixtures'
ActiveRecord::Fixtures.create_fixtures("#{Rails.root}/test/fixtures", "fixtures_file_name")
 104
Author: ajhit406,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-27 16:45:35

Generalmente hay 2 tipos de datos de semilla requeridos.

  • Datos básicos en los que puede basarse el núcleo de su solicitud. Yo llamo a esto las semillas comunes.
  • Datos ambientales, por ejemplo, para desarrollar la aplicación es útil tener un montón de datos en un estado conocido que podamos usar para trabajar en la aplicación localmente (la respuesta de Factory Girl anterior cubre este tipo de datos).

En mi experiencia siempre me encontré con la necesidad de estos dos tipos de datos. Así que armé una pequeña gema que extiende las semillas de Rails y le permite agregar múltiples archivos de semillas comunes bajo db/seeds/ y cualquier dato de semillas ambientales bajo db/seeds/ENV por ejemplo db/seeds/development.

He encontrado que este enfoque es suficiente para dar a mis datos semilla alguna estructura y me da el poder de configurar mi entorno de desarrollo o puesta en escena en un estado conocido simplemente ejecutando:

rake db:setup

Los accesorios son frágiles y escamosos de mantener, al igual que el sql regular volcado.

 26
Author: james2m,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-09 09:50:19

Factory_bot suena como que hará lo que usted está tratando de lograr. Puede definir todos los atributos comunes en la definición predeterminada y luego sobrescribirlos en el momento de la creación. También puede pasar un id a la fábrica:

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

Cuando se utiliza con faker puede llenar una base de datos muy rápidamente con asociaciones sin tener que meterse con los Accesorios (yuck).

Tengo código como este en una tarea de rake.

100.times do
    Factory(:company, :address => Factory(:address), :employees => [Factory(:employee)])
end
 24
Author: Hates_,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-14 13:42:22

Usar seeds.rb file o FactoryBot es genial, pero estos son respectivamente excelentes para estructuras de datos fijos y pruebas.

El seedbank gem podría darte más control y modularidad a tus semillas. Inserta tareas de rake y también puedes definir dependencias entre tus seeds. Su lista de tareas de rake tendrá estas adiciones (por ejemplo):

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
 21
Author: Yuri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-14 17:25:17

En lugar de usar creaciones explícitas, use archivos YAML. Con una sintaxis simple, puede completar todos los valores de un objeto. En realidad, si sabes algo sobre pruebas de rails, esa es la forma estándar de sembrar la base de datos de pruebas. Echa un vistazo a estas páginas:
http://railspikes.com/2008/2/1/loading-seed-data http://quotedprintable.com/2007/11/16/seed-data-in-rails

 1
Author: YenTheFirst,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-17 16:50:28

Rails tiene una forma incorporada de sembrar datos como se explica aquí.

Otra forma sería usar una gema para siembra más avanzada o fácil, como: banco de semillas.

La principal ventaja de esta gema y la razón por la que la uso es que tiene capacidades avanzadas como dependencias de carga de datos y datos de semilla por entorno.

Agregar una respuesta actualizada ya que esta respuesta fue la primera en Google.

 1
Author: SimonW,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-05 14:21:40

Añádelo en las migraciones de bases de datos, de esa manera todos lo obtienen a medida que se actualizan. Maneje toda su lógica en el código ruby / rails, por lo que nunca tendrá que meterse con la configuración de ID explícita.

 -2
Author: Matt Rogish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-17 19:13:32

La mejor manera es usar accesorios.

Nota: Tenga en cuenta que los accesorios hacen inserciones directas y no usan su modelo, por lo que si tiene devoluciones de llamada que rellenan datos, necesitará encontrar una solución.

 -3
Author: p01nd3xt3r,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-04 02:14:55