[Ruby on rails]バッチ処理で通知の定時削除　通知の未読連絡のメール作成

<h2>初めに</h2>
今回バッチ処理を実装しました。
以下はイメージ画像です。
何日で通知を削除するのがベストなのか定まってなくてすみません・・・。

![スクリーンショット 2021-08-19 17.50.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/f34553ab-506a-be18-37b8-df492837a416.png)

![スクリーンショット 2021-08-19 17.47.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/00bf8879-33ab-d342-2dfc-cc938003e5ec.png)

<h2>バッチ処理って何？</h2>
一定期間経ったらデータを消してくれる機能だと思ってたのですが、
もっと色々なことができるんですね:point_up:
1日１回何時とか、２分起き〜とかに、あらかじめ定めた処理を行ってくれます。
今回行ったのは、1日1回３０日前の通知のデータを消すという作業と、
1日１回未読の通知チェックしてあれば、リマインドメールのようなものを送るというような作業です。
閲覧履歴とか作っていればそこでもバッチ処理使えたな〜と思いました。

<h2>通知機能の実装</h2>

通知機能の実装は以下の記事の通りです。

https://qiita.com/ki_87/items/6feb324140bf5b0349ff

<h2>メーラー作成</h2>

以下を参考に作成しました。

https://qiita.com/kyoooko/items/32df5b5825677627b09a


<details><summary>コード（環境変数使用してます）</summary><div>

環境変数化（セキュリティ対策）については以下の記事です。

https://qiita.com/ki_87/items/82b28f89a8552506a169



```
class ApplicationMailer < ActionMailer::Base
  default from: ENV['KEY']
  layout 'mailer'
end
```

```
class ScheduledProcessingMailer < ApplicationMailer
    
    def check_notice_mail

    users_with_unckecked_notices = User.all.select do |user|
      user.passive_notifications.where(visited_id: user.id, checked: false).count >= 5
    end

    users_with_unckecked_notices_mails = users_with_unckecked_notices.pluck(:email)

    mail(subject: "未読の通知が5件以上あります ※通知は30日で自動削除されます", bcc: users_with_unckecked_notices_mails)
    end
end
```

```perl:check_notice_mail.text
===============================
現在、~~に未読の通知が５件以上あります。
===============================

通知は30日で自動削除されてしまいすので、
ご確認お願いします。



 今後とも よろしくお願いいたします。
  
※このメールは送信専用です。
===============================
===============================
```

</div></details>



<h2>Gemの追加　</h2>

```perl:Gemfile
gem 'whenever', require: false
```

```perl:ターミナル
bundle install
```

```perl:ターミナル
bundle exec wheneverize
```

<h2>まずは処理を書く</h2>
やってほしい処理を書きます。
app/lib/batch/data_reset.rbを作成します。
batchフォルダも、ファイルも手作りです。

正直ファイル名をミスったなあと思います・・・。
あと処理が二つならファイルも分けるべきだったのかな。。とも思います。

```perl:app/lib/batch/data_reset.rb
class Batch::DataReset
  def self.data_reset
    # 投稿を全て削除
    Notification.where("created_at < ?", 30.days.ago.beginning_of_day).delete_all
    p "30日前の通知を全て削除しました"
  end
  
  def self.data_notice
    ScheduledProcessingMailer.check_notice_mail.deliver_now
    p "未読通知をメールしました"
  end
end
```

このファイルを読み込めるように、```config/application.rb```に以下追記します。
ついでにタイムゾーンも東京にします。

```
config.paths.add 'lib', eager_load: true
config.time_zone = 'Tokyo'
```

<h2>決まった時刻に起動する処理を書く</h2>

上でやった```bundle exec wheneverize```のコマンドで、
config/schedule.rbが作成されるかと思いますので、
以下を追記します。

```perl:config/schedule.rb
env :PATH, ENV['PATH']
set :output, 'log/cron.log'
set :environment, :development
 every 1.minutes do
  # every 1.days, at: '0:10 am' do
    runner "Batch::DataReset.data_reset"
 end

# every 1.days, at: '0:10 am' do
every 1.minutes do
     runner "Batch::DataReset.data_notice"
end
```
動作確認しやすいように、1日１回の処理をコメントアウトし、
１分毎起動するようにしてあるので注意してください！！

```PATH, ENV['PATH']```環境変数は特に定義してませんが、、
これを書かないとエラーになるそうです。
```set :output, 'log/cron.log'```ここにバッチ処理の履歴が入ります。
```set :environment, :development```
本番環境では、ここを```:development```ではなく、
```:production```にする必要があります！！
あとは、1日１回何時に、何を行うか〜の記述ですが、
```app/lib/batch/data_reset.rb```に書いた作業を呼び出しています。

以下を実行しバッチ処理の内容を反映しましょう。
処理内容更新したら毎回実行する必要があると思います。

```
bundle exec whenever
```

![スクリーンショット 2021-08-19 19.17.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/492af9b5-ccb4-30f5-8d26-6e52b19d46b8.png)


```
bundle exec whenever --update-crontab
```
以下のように出力があるかと思います！
```[write] crontab file updated```



<h2>起動と停止</h2>

以下のコマンドで処理が起動します。
未読の通知をたくさん用意しておきます。

```
sudo systemctl start crond
```

以下のコマンドで実行結果が見れます。

```
sudo tail -f log/cron.log
```

![スクリーンショット 2021-08-19 18.52.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/e404defe-238f-fc66-284c-32947fb5dfdf.png)

なんだか他のながーい記述があればエラーです。
私は、メーラーのviewファイルの名前を間違えていてエラーが出てしまいました・・・。

停止は以下のコマンドです。

```
sudo systemctl stop crond
```