#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
Комментарии:
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']
вдохновлено блогом Красимира Ангелова