Почему задача Rake в цикле выполняется только один раз? - PullRequest
16 голосов
/ 28 января 2011

У меня есть приложение rails, которое подключается к нескольким базам данных.Я написал пользовательскую задачу rake, которая выглядит следующим образом:

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

Проблема заключается в том, что задача выполняет db: migrate только для пользователей [0] user (первый пользователь в коллекции) и ошибок нет, просто останавливается молча...

Вот вывод из 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 

Я понятия не имею, почему остальные пользователи не переносятся.

Ответы [ 2 ]

21 голосов
/ 17 апреля 2014

Я нашел ответ в источнике Rake:

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

Он говорит, что вы должны

Повторно включите задачу, позволяя выполнять ее задачи, если задача вызывается снова. например. Я недавно использовал это в своем проекте так:

# 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

Итак, я запускаю каталог граблей: загружаю [some_file] каждый цикл.

Надеюсь, это поможет. Также см. https://stackoverflow.com/a/1290119/3082929

18 голосов
/ 14 марта 2011

Я забыл точные внутренние данные, но способ, которым работает Rake, заключается в том, что invoke будет выполнять каждую задачу только в случае необходимости (другими словами, один раз).

Попробуйте вызвать execute для последующих вызовов:

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

При первом прохождении цикла вам понадобится invoke, поскольку он сначала вызывает необходимые условия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...