2011-01-27 21 views
15

Tengo una aplicación de rieles que se conecta a múltiples bases de datos. Escribí tarea rastrillo costumbre que tiene este aspecto:¿Por qué una tarea de Rake en un ciclo se ejecuta solo una vez?

task :migrate_accounts_schema => [:environment] do |t| 
    users = User.find :all, :conditions => ["state = 2"], :order => "id asc" 
    users.each do |user|    
    if user.state == 2 
     ActiveRecord::Base.establish_connection(
     :adapter => "postgresql", 
     :host  => user.database_host, 
     :port  => user.database_port, 
     :username => user.subdomain, 
     :password => "#{user.database_password}", 
     :database => user.database_name 
    ) 
     Rake::Task["db:migrate"].invoke 
    end 
    end 
end 

El problema es que la tarea se ejecuta db: migrate sólo para los usuarios [0] usuario (primer usuario en la colección) y no hay ningún error, simplemente stoppes en silencio .. .

Aquí está la salida del rastrillo --trace

** Invoke app:migrate_accounts_schema (first_time) 
** Invoke environment (first_time) 
** Execute environment 
** Execute app:migrate_accounts_schema  
** Invoke db:migrate (first_time) 
** Invoke environment 
** Execute db:migrate 
** Invoke db:schema:dump (first_time) 
** Invoke environment 
** Execute db:schema:dump 
** Invoke db:migrate 

no tengo ni idea de por qué el resto de usuarios no consigue migrar.

Respuesta

17

Olvidé las partes internas exactas, pero la forma en que funciona Rake es que invoke solo ejecutará cada tarea si es necesario (en otras palabras, una vez).

intentar llamar a ejecutar en llamadas posteriores:

Rake::Task["db:migrate"].execute

La primera vez a través del bucle que necesita invoke ya que invoca los requisitos previos en primer lugar.

+0

Comprobar la fuente [aquí] (http://rake.rubyforge.org/classes/Rake/Task.html) – lebreeze

+0

Se trabajó :) :) de agradecimiento –

+2

Esto parece muy contrario a la intuición para mí. ¿Alguna idea de por qué lo hicieron así? – marcovtwout

18

He encontrado respuesta en la fuente Rake:

http://rake.rubyforge.org/classes/Rake/Task.html#M000115

Se dice que usted tiene que

Vuelva a activar la tarea, permitiendo a sus tareas a ejecutar si la tarea se invoca de nuevo.

e.g. He utilizado este recientemente en mi proyecto de esta manera:

# db/seed.rb 
Rake::Task['catalog:destroy'].invoke 

files = Dir.glob("private/catalog/*").sort 
files.each do |file| 
    next unless File.extname(file) == '.xlsx' 
    puts file.split('/').last 
    Rake::Task['catalog:upload'].invoke(file) 
    Rake::Task['catalog:upload'].reenable 
    puts 
end 

Así que corro catálogo rastrillo: subir [some_file] cada bucle.

Espero que esto ayude. Véase también https://stackoverflow.com/a/1290119/3082929

+0

Estoy bastante seguro de que esta es la respuesta técnicamente correcta ('# reenable', no solo' # execute') –

Cuestiones relacionadas