2009-01-06 10 views
17

Me gustaría saber cuál es la forma preferida de agregar registros a una tabla de base de datos en una migración de Rails. He leído en el libro de Ola Bini (jruby on Rails) que hace algo como esto:Añadir filas en migraciones

class CreateProductCategories < ActiveRecord::Migration 

    #defines the AR class 
    class ProductType < ActiveRecord::Base; end 

    def self.up 

    #CREATE THE TABLES... 

    load_data 
    end 
    def self.load_data 
    #Use AR object to create default data 
    ProductType.create(:name => "type") 
    end 
end 

Ésta es agradable y limpio, pero por alguna razón, no funciona en las hormas versiones de rieles ...

La pregunta es, ¿cómo llenas la base de datos con datos predeterminados (como usuarios o algo así)?

Gracias!

+0

Eso es más o menos lo que hago, por favor incluya el error que está recibiendo. –

+0

El código completo es este: http://pastie.org/pastes/251539 Y el error es 'CreateProductCategories no falta constante ProductType' –

+0

Use seeds.rb para esto. – ironic

Respuesta

9

Puede usar accesorios para eso. Significa tener un archivo yaml en algún lugar con los datos que desea insertar.

Aquí es un conjunto de cambios que cometí para esto en uno de mi aplicación:

db/migrate/004_load_profiles.rb

require 'active_record/fixtures' 

class LoadProfiles < ActiveRecord::Migration 
    def self.up 
    down() 

    directory = File.join(File.dirname(__FILE__), "init_data") 
    Fixtures.create_fixtures(directory, "profiles") 
    end 

    def self.down 
    Profile.delete_all 
    end 
end 

db/migrate/init_data/profiles.yaml

admin: 
name: Admin 
    value: 1 
normal: 
name: Normal user 
    value: 2 
3

sus migraciones tienen acceso a todos sus modelos, por lo que no debería crear una clase dentro de la migración.

Estoy utilizando los últimos rieles, y puedo confirmar que el ejemplo que publicaste definitivamente DEBERÍA funcionar.

Sin embargo, las migraciones son una bestia especial. Siempre y cuando esté claro, no veo nada malo con un ActiveRecord::Base.connection.execute("INSERT INTO product_types (name) VALUES ('type1'), ('type2')").

La ventaja de esto es que puede generarlo fácilmente mediante el uso de algún tipo de GUI o front-end web para rellenar los datos de inicio y luego hacer un mysqldump -uroot database_name.product_types.

Lo que hace las cosas más fáciles para el tipo de persona que va a ejecutar sus migraciones y mantener el producto.

35

La documentación de la API rieles para las migraciones muestra una manera más sencilla de lograr esta.

http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

class CreateProductCategories < ActiveRecord::Migration 
    def self.up 
    create_table "product_categories" do |t| 
     t.string name 
     # etc. 
    end 

    # Now populate the category list with default data 

    ProductCategory.create :name => 'Books', ... 
    ProductCategory.create :name => 'Games', ... # Etc. 

    # The "down" method takes care of the data because it 
    # drops the whole table. 

    end 

    def self.down 
    drop_table "product_categories" 
    end 
end 

analizadas en los carriles 2.3.0, pero esto debería funcionar para muchas versiones anteriores también.

+1

Esto todavía funciona desde Rails 3.0.3, para el registro. – coreyward

+0

Es bueno saberlo, gracias. –

+0

La forma recomendada es usar seeds.rb. – ironic

7

También se puede definir en el archivo de seeds.rb, por ejemplo:

Grid.create :ref_code => 'one' , :name => 'Grade Única' 

carrera y después de:

rake db:seed 
0

realmente debería no utilizar

ProductType.create 

en su migraciones.

He hecho algo similar, pero a la larga no se garantiza que funcionen.

Cuando ejecuta la migración, la clase de modelo que está utilizando es la que se encuentra en el momento de ejecutar la migración, no la que se encontraba en el momento en que creó la migración. Deberá asegurarse de que nunca cambie su modelo de tal forma que evite que la migración se ejecute.

que son mucho mejor que ejecuta SQL, por ejemplo:

[{name: 'Type', ..}, .. ].each do |type| 
    execute("INSERT INTO product_types (name) VALUES ('#{type[:name]} ..) 
end 
Cuestiones relacionadas