2011-01-27 7 views
15

Ho un'applicazione per le rotaie che si collega a più database. Ho scritto task rake personalizzata che assomiglia a questo:Perché un'operazione Rake in un ciclo viene eseguita solo una volta?

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 

Il problema è che compito esegue db: migrate solo per gli utenti [0] utente (primo utente della raccolta) e non v'è nessun errore, solo stoppes silenzio .. .

Ecco uscita dal rake --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 

non ho idea del perché il resto degli utenti non ottengono migrato.

risposta

17

Ho dimenticato gli interni esatti ma il modo in cui Rake funziona è che invoke eseguirà solo ogni attività se necessario (in altre parole una volta).

provare a chiamare eseguire sulle chiamate successive:

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

La prima volta attraverso il ciclo è necessario invoke come invoca i prerequisiti prima.

+0

Verificare la fonte [qui] (http://rake.rubyforge.org/classes/Rake/Task.html) – lebreeze

+0

Ha funzionato :) :) di ringraziamento –

+2

Questo sembra molto intuitivo per me. Qualche idea sul perché l'abbiano fatta in questo modo? – marcovtwout

18

ho trovato risposta nella fonte Rake:

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

Si dice che si deve

Riattivare il compito, consentendo ai suoi compiti da eseguire se il compito viene richiamato di nuovo.

ad es. Ho usato questo di recente sul mio progetto in questo modo:

# 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 

Allora corro catalogo rake: caricare [un_file] ogni ciclo.

Spero che questo aiuti. vedere anche https://stackoverflow.com/a/1290119/3082929

+0

Sono abbastanza sicuro che questa sia la risposta tecnicamente corretta ('# reenable', non solo' # execute') –

Problemi correlati