Rails - Rake Task Hooks

- 2 mins read
rails tutorial tips

sample task

task :migrate_users do
  User.all.each { |u| u.migrate! }
end

to run the task rake migrate_users

what if we want to track elapsed time when run the task?

# migrate_users.rake

task :migrate_users do
  start_at = Time.current

  User.all.each { |u| u.migrate! }

  end_at = Time.current

  puts "Elapsed time: #{end_at - start_at}"
end

Utilize rake hooks

ideal order should be like this

before_hookmain_taskafter_hook

the actual order execution

before_hookafter_hookmain_task

how to fix

# migrate_users.rake

task :before_hook
  @start_at = Time.current
end

task :after_hook
  at_exit do
    end_time = Time.current
    duration = end_time - @start_time
    puts "Elapsed time: #{duration}"
  end
end

task :migrate_users do
  User.all.each { |u| u.migrate! }
end

Rake::Task['numbers'].enhance [:before_hook, :after_hook]

applying as global hooks

# Rakefile

task :before_hook do
  @start_time = Time.current
end

task :after_hook do
  at_exit do
    end_time = Time.current
    duration = end_time - @start_time
    puts "Elapsed time: #{duration}"
  end
end

tasks = Rake.application.tasks

tasks.each do |task|
  next if [Rake::Task['before_hook'],
           Rake::Task['after_hook']].include?(task)

  task.enhance([:before_hook, :after_hook])
end

reference: https://t2013anurag.medium.com/rails-adding-global-hooks-for-rake-tasks-7faf0844364