Ruby
Rails
rake

結構便利!RailsでTask実行の結果を通知するTaskNotifierクラス

Railsのtaskを実行して成功/失敗の結果をslackなどに通知したいということはよくあると思いますが普通に書くとこんな感じになります。

task :hoge => :environment do |task, args|
  begin
    # タスクの処理
    # ...
    SlackNotifier.notify(message: "Success to exec task hoge")
  rescue => e
    SlackNotifier.notify(message: "Fail to exec task hoge #{e.message}")
  end
end

でこれが1つだけなら良いですが沢山タスクを書いていくとどんどん冗長になっていきます。

task :hoge => :environment do |task, args|
  begin
    # タスクの処理
    # ...
    SlackNotifier.notify(message: "Success to exec task hoge")
  rescue => e
    SlackNotifier.notify(message: "Fail to exec task hoge #{e.message}")
  end
end

task :baz => :environment do |task, args|
  begin
    # タスクの処理
    # ...
    SlackNotifier.notify(message: "Success to exec task baz")
  rescue => e
    SlackNotifier.notify(message: "Fail to exec task baz #{e.message}")
  end
end

task :bar => :environment do |task, args|
  begin
    # タスクの処理
    # ...
    SlackNotifier.notify(message: "Success to exec task hoge")
  rescue => e
    SlackNotifier.notify(message: "Fail to exec task bar #{e.message}")
  end
end

そこでTaskNotifierクラスを書いてみました。
(notifierで使うクラスは自分がお使いのクラスを設定してください)

class Util::TaskNotifier
  attr_accessor :task_name, :success_message, :fail_message

  def initialize(task, notifier = SlackNotifier)
    @task = task
    @notifier = notifier
  end

  def exec
    begin
      yield(self)
      @notifier.notify(message: success_message || default_success_message)
    rescue => e
      @notifier.notify(message: fail_message || default_fail_message(e))
    end
  end

  private
  def default_success_message
    "Success to exec task #{@task.name}"
  end

  def default_fail_message(e)
    "Fail to exec task #{@task.name} because #{e.message}"
  end
end

呼びだすときは処理内容をTaskNotifier#exec内で書くことで成功/失敗時の通知はTaskNotifierクラス内で勝手にやってくれます

task :foo => :environment do |task, args|
  Util::TaskNotifier.new(task).exec do |notifier|
    print("foo")
  end
end

Slack_-_umataro.jpg

またカスタムでメッセージを表示したいときはカスタム値をブロック内で設定することで個別にメッセージ内容をコントロールできます。

task :foo => :environment do |task, args|
  Util::TaskNotifier.new(task).exec do |notifier|
    notifier.fail_message = "ooooops!" #カスタムメッセージを設定
    print("foo")
  end
end

Slack_-_umataro.jpg

あんなに冗長だったタスクの羅列はこんな風にスッキリ書けるようになりました。

task :hoge => :environment do |task, args|
  Util::TaskNotifier.new(task).exec do |notifier|
    # タスクの処理
    # ...
  end
end

task :baz => :environment do |task, args|
  Util::TaskNotifier.new(task).exec do |notifier|
    # タスクの処理
    # ...
  end
end

task :bar => :environment do |task, args|
  Util::TaskNotifier.new(task).exec do |notifier|
    # タスクの処理
    # ...
  end
end

RakeTaskをよく書く皆様良ければ使ってみてください :thumbsup: