# 使用 whenever gem 建立Cron job ###### tags: `RoR` `gem` 試想一下,若每個月都要做同樣的一件事情,例如:寄通知信給外部廠商、公司同仁、客戶等等,是不是又會增加一件行政作業。那不妨寫一段程式讓它自己跑,節省時間。 ## 什麼是Cron? Cron 是一種工作排程系統,適用於Linux & MacOS兩個作業系統. 任何程式語言都可以執行Cron,包含Ruby. ## 實作版本 ruby : 3.1.2 Rails : 6.0.6 系統 : Mac OS13 ## 開始 1. 安裝 Whenever Gem,記得要 $ **bundle install** ``` ruby # gemfile gem 'whenever', require: false ``` 2. 建立config/schedule.rb,也可以輸入指令,自動生成檔案。 ```shell $ bundle exec wheneverize . ``` 3. 編輯schedule.rb ```ruby # 每隔多久時間,要做什麼任務。 # 以'notify:send_messages'為例 # notify -> 檔案名稱 # send_messages -> 執行任務名稱 # 同一個檔案內,可以有多個task,群組的概念。 every 1.minute do rake 'notify:send_message' end ``` 4. 在lib/tasks 新增 notify.rake檔案 ```ruby # namespace 寫上file名稱 :notify # desc 描述想要做的事情 Send out message # task 寫上執行任務名稱 send_message: namespace :notify do desc 'Send out message' task send_message: :environment do puts 'hello world' # 要執行內容 end end ``` 5. 在終端機執行 $ **rake notify:send_message** ## 進階 在大型專案中,若要執行的內容很大一長串,可能還有些判斷,或是共用,為了更容易維護,常會使用模組,放在app層底下,例如,產品提供ABCD四種服務,D服務中又有d服務。 1. 資料結構類似這樣 ![](https://i.imgur.com/uaCFrso.png) 2. 編輯 service_d.rb ```ruby # 宣告一個模組D,和該file名稱一致 # 宣告一個class ServiceD module D class ServiceD # 執行內容 puts 'say hi ' end end ``` 3. 如何讀取,在lib/tasks 新增 notify.rake檔案,編輯內容 ```ruby namespace :notify do desc 'Send out message' task send_message: :environment do D::ServiceD end end ``` 4. 在終端機執行 $ **rake notify:send_message** ,就可以看到訊息改變了。