Запуск заданий с помощью Rake в Ruby on Rails
Иногда возникает необходимость запускать некоторые задания, задачи веб-приложения из командной строки или через cron (планировщик заданий в Unix-системах). Как раз для этой цели можно использовать задания, задачи Rake. Например, каким-то образом обработать собранные данные или произвести очистку баз данных или удаление устаревших файлов, для чего не требуется запуск непосредственно веб-приложения.
Список заданий, задач
Если выполнить команду $ rake -T
(или $ rake --tasks
), то можно увидеть список и описание всех возможных задач rake. Все пользовательские задания, задачи располагаются в подкаталоге lib/tasks вашего приложения, и должны иметь расширение .rake. Все задачи - это программы Ruby.
Задание, задача
Создадим для примера файл: lib/tasks/example.rake:
task :hello do puts 'Hello world!' end
Теперь команда $ rake hello
выдаст: Hello, world!
Цепочка заданий, задач
В файле может быть прописано множество задач, каждая из которых может быть запущена с помощью $ rake <task_name>
. Задания могут выполнятся отдельно, но так же можно связать их в цепочку заданий:
task :hello do puts "Hello, World!" end task :chain => :hello do puts "Chain task..." end
Выполнение команды $ rake chain
выведет:
Hello, World! Chain task...
И в то же время у нас сохранится и задача hello
.
Запуск задания, задачи в среде Rails
Этот же самый механизм цепочки заданий используется для того, чтобы запустить задачу в среде выполнения Rails - будут доступны все классы и модули, которые вы используете в своем Rails-приложении (веб-приложении), если вам необходимо, например, работа моделями базы данных (ActiveRecord). Достаточно включить в цепочку вашей задачи задачу :environment :
task :hello do puts "Hello, World!" end task :chain => :hello do puts "Chain task..." end task :rails_task => :environment do puts "I can use Rails" # предполагается, что у нас есть модель Product product = Product.first puts product.name end
Пространство имен заданий, задач
Задания можно расположить в общем пространстве имен, выделить отдельное пространство имен. Например, если задания выполняют обработку какого-либо одного объекта, но имеют различные действия:
namespace :product do task :first => :environment do product = Product.first puts product.title end task :last => :environment do product = Product.last puts product.title end end
Для запуска таких задач необходимо использовать $ rake <namespace>:<task_name>.
В нашем случае: $ rake product:first
или $ rake product:last.
Группы заданий, задач
Можно так же создать группу заданий - задачу, которая объединяет в себе несколько:
task :first do puts "First" end task :second do puts "Second" end task :task_all => [:second, :first]
При чем задания будут выполнены именно в указанном вами (в массиве) порядке.
Запуск других задач
Задача может запускать другие, в том числе и в определенном namespace.
task :my_task => 'other_task' task :ns_task => 'other:task'
Описание задания, задачи
Очень желательно, чтобы каждое задание имело свое описание. При чем rake -T
не отображает задачу в списке задач, пока она не имеет описания. Просто добавляем desc 'описание'
перед task
:
desc 'First task' task :first do puts "First" end desc 'Second task' # пустые строки не имеют значения между описанием и самой задачей task :second do puts "Second" end desc 'Task all is a :second and :first' task :task_all => [:second, :first]
Запуск задания в cron
Пример команды запуска rake в crontab
*/1 * * * * cd /rails_app_path && /bin/bash -l -c '/path_to_rake/rake RAILS_ENV=production task_name' >> /rails_app_path/log/cron.log 2>&1
Чтобы не искать местонахождение rake
, полезно использовать команду which
*/1 * * * * cd /rails_app_path && /bin/bash -l -c '`/usr/bin/which rake` RAILS_ENV=production task_name' >> /rails_app_path/log/cron.log 2>&1