2011-10-13 18 views
14

Me gustaría tener una tarea de rake para truncar todas las tablas. Tengo found one en Internet, pero se supone que es solo para Rails 2 y no funciona para Rails 3 (el problema está en obtener una conexión de base de datos).Rake para truncar todas las tablas en Rails 3

rake db:reset no es una opción, porque estoy usando PostgreSQL y también descarta al usuario. Por lo tanto, la migración falla. Solo quiero borrar los datos.

¿Ustedes tienen algo para mí?

+0

Nunca he visto un usuario de postgres que se descarta al hacer un 'db: reset'. ¿Mi configuración es radicalmente diferente a la tuya? – thekingoftruth

Respuesta

32

He encontrado esto a través de Google, y luego recibí una solución mucho más simple que la aprobada, por lo que aquí está: Use la gema database_cleaner. Aquí están los pasos.

En su Gemfile (ejecutar paquete después de haber modificado):

gem 'database_cleaner' # you might want to limit this to the dev and staging group 

Con esa gema en su lugar, la declaración DatabaseCleaner.clean_with :truncation truncará la base de datos. Añadiéndolo a una tarea rake es trivial:

# tasks/db/clean.rake 

namespace :db do 

    desc "Truncate all existing data" 
    task :truncate => "db:load_config" do 
    DatabaseCleaner.clean_with :truncation 
    end 

end 

Eso es todo. También puede usar la línea DatabaseCleaner.clean_with :truncation dentro de su archivo db/seeds.rb directamente para que no se olvide de truncar la base de datos antes de sembrar.

+1

La línea en el archivo de inicialización era exactamente lo que necesitaba –

8

Según la respuesta Chris Ledet, esto se convierte en mucho más simple:

ActiveRecord::Base.connection.tables.each do |table| 
    ActiveRecord::Base.connection.execute("TRUNCATE TABLE #{table};") 
end 
+0

Igual que mi primer comentario a la respuesta de Chris. ¡Pero gracias! – lzap

3

Esto hará que todas las tablas de la base de datos, encontrar un modelo asociado a esa mesa y llamar # destroy_all.

tables = ActiveRecord::Base.connection.tables 
tables.each do |tbl| 
# "users" => User 
tbl.classify.constantize.destroy_all 
end 
+0

Estoy más interesado en la tarea de Rake: cómo implementarla. El ejemplo vinculado solo funciona con Rails 2.x. Sigo intentando eso. – lzap

+0

incorrecto Este ejemplo funciona con Rails 3 y 3.1. Nada te impide ponerlo en una tarea de rake. –

+0

Lo sentimos, pero no proporcionó información sobre cómo hacer una conexión en Rails 3 (en una tarea de rake). Es una gran diferencia en Rails 2 y Rails 3. – lzap

19

Así que editó el ejemplo enlazado en esto:

namespace :db do 
    desc "Truncate all existing data" 
    task :truncate => "db:load_config" do 
    begin 
    config = ActiveRecord::Base.configurations[::Rails.env] 
    ActiveRecord::Base.establish_connection 
    case config["adapter"] 
     when "mysql", "postgresql" 
     ActiveRecord::Base.connection.tables.each do |table| 
      ActiveRecord::Base.connection.execute("TRUNCATE #{table}") 
     end 
     when "sqlite", "sqlite3" 
     ActiveRecord::Base.connection.tables.each do |table| 
      ActiveRecord::Base.connection.execute("DELETE FROM #{table}") 
      ActiveRecord::Base.connection.execute("DELETE FROM sqlite_sequence where name='#{table}'") 
     end                                
     ActiveRecord::Base.connection.execute("VACUUM") 
    end 
    end 
    end 
end 

Este ejemplo se basa en código de abajo de Chris Ledet (gracias) y trabaja con rieles 3.X.

Gracias por todos los consejos.

+0

¡Funciona con * Rails 3 *! – lzap

+2

He añadido esto para que funcione con mysql2: 'ActiveRecord :: Base.connection.execute (" TRUNCATE # {table} ") if table! =" Schema_migrations "'. Y 'cuando" mysql "," mysql2 "," postgresql "' De lo contrario, Rails quería migrar todo de nuevo. –

+0

Ya definitivamente tiene que haber un 'a menos tabla == 'schema_migrations'' en esas líneas truncadas. – nzifnab

6

Siempre se puede migrar a la versión 0, así:

rake db:migrate VERSION=0 

De esa manera usted ni siquiera tiene que truncar las tablas, y luego se puede migrar de nuevo. La única pega es que necesita que sus migraciones down funcionen correctamente.

Esta solución funciona en rieles 3, a pesar del hecho de que las versiones están basadas en la fecha y hora.

Esta solución es como se ve aquí: https://stackoverflow.com/a/1196822/241367

Además, siempre se puede ejecutar el siguiente, suponiendo que su schema.rb es hasta la fecha:

rake db:schema:load 

Y como @kikito sugiere, puede ejecutar database_cleaner (es lo que cucumber y rspec les gusta usar entre las pruebas) de esta manera:

DatabaseCleaner.clean_with :truncation 
+1

Me gusta la idea de usar db: schema: load. Eso es muy limpio y hace exactamente lo que quiero, que es restablecer la base de datos sin tener que soltar y volver a crear. –

1

La respuesta dada por lzap tiene un problema específico. Rails quiere ejecutar todas las migraciones de nuevo. El siguiente código es el sugerido por Anthony Alberto y funciona. Esta adición comprueba con la tabla schema_migrations

namespace :db do 
    desc "Truncate all existing data" 
    task :truncate => "db:load_config" do 
    begin 
    config = ActiveRecord::Base.configurations[::Rails.env] 
    ActiveRecord::Base.establish_connection 
    case config["adapter"] 
     when "mysql", "postgresql" 
     ActiveRecord::Base.connection.tables.each do |table| 
      ActiveRecord::Base.connection.execute("TRUNCATE #{table}") if table != "schema_migrations" 
     end 
     when "sqlite", "sqlite3" 
     ActiveRecord::Base.connection.tables.each do |table| 
      ActiveRecord::Base.connection.execute("DELETE FROM #{table}") if table != "schema_migrations" 
      ActiveRecord::Base.connection.execute("DELETE FROM sqlite_sequence where name='#{table}'") if table != "schema_migrations" 
     end                                
     ActiveRecord::Base.connection.execute("VACUUM") 
    end 
    end 
    end 
end 
Cuestiones relacionadas