Read more

Maintaining custom application tasks in Rails

Emanuel
January 15, 2024Software engineer at makandra GmbH

Here are some hints on best practices to maintain your tasks in larger projects.

Rake Tasks vs. Scripts

  • The Rails default is using rake tasks for your application tasks. These live in lib/tasks/*.
  • In case you want to avoid rake for your tasks and just use plain ruby scripts, consider lib/scripts/* as folder.

Keeping tasks slim

Illustration online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
Read more Show archive.org snapshot

For readability and testing it's easier to keep your tasks slim.

Example:

lib/gitlab/maintenance_tasks/user_export.rb:

module Gitlab
  module MaintenanceTasks
    class UserExport
      def export
        # Your code of exporting all users e.g. into a XSLX file
      end
    end
  end
end

As rake task: lib/tasks/gitlab.rb:

# bundle exec rake gitlab:user_export

namespace :gitlab do
  desc 'Export all users as XSLX'
  task user_export: :environment do
    Gitlab::MaintenanceTasks::UserExport.new.export
  end
end

As plain ruby script: lib/scripts/user_export.rb:

# bundle exec rails runner -e development lib/scripts/user_export.rb

Gitlab::MaintenanceTasks::UserExport.new.export

Testing should not be optional

Tasks should be tested the same way as other code, even if they are only run once.

Example:

spec/lib/gitlab/maintenance_tasks/user_export_spec.rb:

describe Gitlab::MaintenanceTasks::UserExport do
  it 'should export all users as XLSX file' do
    # Your code for testing all edge cases in the user export
  end
end

As rake task: spec/lib/tasks/gitlab_spec.rb:

describe 'lib/scripts/gitlab.rb' do   
  it 'calls the user export' do
    Rake::Task['gitlab:user_export'].invoke
      
    # Your code for testing e.g. that a file user_export.xlsx is written to disk (smoke test)
  end
end

As plain ruby script: lib/scripts/gitlab_spec.rb:

describe 'lib/scripts/gitlab.rb' do
  let(:script) { Rails.root.join(subject) }
    
  it 'calls the user export' do
    load(script)
    
    # Your code for testing e.g. that a file user_export.xlsx is written to disk (smoke test)
  end
end

Further reading

Emanuel
January 15, 2024Software engineer at makandra GmbH
Posted by Emanuel to makandra dev (2024-01-15 15:25)