Переопределение задач рейкинга rails по умолчанию

#ruby-on-rails #rake

#ruby-on-rails #рейк

Вопрос:

У меня есть проект Rails 2.2, в котором я хочу переопределить функциональность rake db:test:prepare задачи. Я думал, что это сработает, но это не так:

 #lib/tasks/db.rake
namespace :db do
  namespace :test do
    desc "Overridden version of rails' standard db:test:prepare task since the schema dump used in that can't handle DB enums"  
    task :prepare => [:environment] do
      puts "doing db:structure:dump"
      Rake::Task['db:structure:dump'].invoke
      puts "doing db:test:clone_structure"
      Rake::Task['db:test:clone_structure'].invoke
    end   
  end
end
  

Я получаю поведение стандартной задачи. Если я изменю название задачи на :prepare2 , а затем выполню rake db:test:prepare2 , то она будет работать нормально. Естественный вывод, который я делаю из этого, заключается в том, что мои задачи rake определяются раньше встроенных в Rails, поэтому моя переопределяется стандартной :prepare задачей.

Кто-нибудь может увидеть, как я могу это исправить? Я бы предпочел переопределить это, чем использовать новую задачу. Спасибо, Макс

Комментарии:

1. Может быть, вы можете напрямую изменить файл Rakefile в RAILS_ROOT?

Ответ №1:

Если вы определяете задачу rake, которая уже существует, ее выполнение добавляется к выполнению исходной задачи; обе задачи будут выполнены.

Если вы хотите переопределить задачу, вам сначала нужно очистить исходную задачу:

 Rake::Task["db:test:prepare"].clear
  

Также полезно отметить, что после выполнения задачи в rake она больше не будет выполняться, даже если вы вызовете ее снова. Это сделано специально, но вы можете вызвать .reset задачу, чтобы разрешить ее повторный запуск.

Комментарии:

1. Ах, похоже, что это тоже работает и синтаксис намного приятнее. Спасибо!

2. Не беспокойтесь 🙂 Я думаю, что это может быть первый раз, когда кто-то принял мой ответ! 😀

3. Это может привести к сбою, если рассматриваемая задача не существует (например, если вы работаете в режиме производства или разработки). Чтобы заставить его работать, даже если задача не существует, сначала создайте неявную пустую задачу: task :default => []; Rake::Task[:default].clear

4. Рейк::Задача.очистить Рейк:: задача[‘rake_task’].повторно включить рейк:: задача [‘rake_task’].вызвать Это нормально?

Ответ №2:

Вы должны удалить задачу по умолчанию, прежде чем добавлять свою собственную:

 Rake.application.instance_variable_get('@tasks').delete('db:test:prepare')
namespace 'db' do
  namespace 'test' do
    task 'prepare' do
      # ...
    end
  end
end
  

Довольно популярной идиомой является создание удобного метода, называемого remove_task примерно так:

 Rake::TaskManager.class_eval do
  def remove_task(task_name)
    @tasks.delete(task_name.to_s)
  end
end

def remove_task(task_name)
  Rake.application.remove_task(task_name)
end
  

(Источник: drnic/newgem )

Комментарии:

1. Спасибо, Алекс, верхняя из них подходит для меня, а также более очевидна в отношении того, что происходит, ради всех остальных, кто смотрит на это. Приветствия

Ответ №3:

Создайте новый файл project.rake в lib/tasks/ и вставьте в него приведенный ниже код.

 namespace :mv do
desc "Display hint and info for your rails 4 project"
task info: :environment do
    puts 'Run rake test to test'
end
end

task(:default).clear.enhance ['mv:info']
  

вдохновлено блогом Красимира Ангелова