🐈

Rake + Wheneverでブログのステータスを自動的に変更するアプリを作成

2021/10/04に公開

目的

シンプルなブログアプリに記事のステータスをcronタスクにて自動的に変更する機能を実装する。

新規の技術・機能の概要

Rake
Rubyで記述されたビルドツール
Whenever
railsにてcronタスクを簡単に設定するgem
執筆時の対象Version
Rails:5.2.6
Whenever:1.0.0

実装方法

セットアップ

terminal
# アプリの新規作成
rails new blog_sample
cd blog_sample
terminal
# scaffoldにてBlogモデルを生成
rails g scaffold Blog title:string content:text
db/migrate/*******_create_blogs.rb
class CreateBlogs < ActiveRecord::Migration[5.2]
  def change
    create_table :blogs do |t|
      t.string :title
      t.text :content
      # マイグレーションファイルに記事のステータスを追記
+     t.integer :state, default: 0, null: false
      t.timestamps
    end
  end
end
ternimal
# DBを生成
rails db:create
# マイグレーションを実行
rails db:migrate
config/routes.rb
Rails.application.routes.draw do
# root_pathを設定
+ root to: 'blogs#index'
  resources :blogs
end

記事ステータスの設定

Blogのmodelとviewの設定を行います。

app/models/blog.rb
class Blog < ApplicationRecord
  # 記事ステータスを設定
+ enum state: { draft: 0, published: 1, publish_wait: 2}
end
app/views/blogs/index.html.erb
---省略---
  <tbody>
    <% @blogs.each do |blog| %>
      <tr>
        <td><%= blog.title %></td>
        <td><%= blog.content %></td>
	# 記事ステータスを表示
+       <td><%= blog.state %></td>
        <td><%= link_to 'Show', blog %></td>
        <td><%= link_to 'Edit', edit_blog_path(blog) %></td>
        <td><%= link_to 'Destroy', blog, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
---省略---
app/views/blogs/show.html.erb
 <p>
   <strong>Title:</strong>
   <%= @blog.title %>
 </p>

 <p>
   <strong>Content:</strong>
   <%= @blog.content %>
 </p>
# 記事ステータスを表示
+ <p>
+ <strong>State:</strong>
+ <%= @blog.state %>
+ </p>
---省略---
app/views/blogs/_form.html.erb
---省略---
  <div class="field">
    <%= form.label :title %>
    <%= form.text_field :title %>
  </div>

  <div class="field">
    <%= form.label :content %>
    <%= form.text_area :content %>
  </div>
 # 記事ステータスを入力
+ <div class="field">
+   <%= form.label :state %>
+   <%= form.select :state, Blog.states.keys.to_a, {} %>
+ </div>

  <div class="actions">
    <%= form.submit %>
  </div>
 <% end %>

記事ステータスを変更するRakeタスクを設定

terminal
# Rakeタスク「change_state」を作成
rails g task change_state
lib/tasks/change_state.rake
 # 下記を追記 記事ステータスがpublish_wait:2の記事をpublished:1へ変更する
 namespace :change_state do
+  desc "Blogのstateを変更"
+  task :change_published => :environment do
+    Blog.where(state:2).find_each do |blog|
+      blog.published!
+    end
+  end
 end
terminal
# 下記のコマンドを実行、ズラズラと出力結果が表示される。
rake -vT
(省略)
rake change_state:change_published      # Blogのstateを変更
(省略)
# 下記のコマンドを実行するとrakeタスクが実施される
rake change_state:change_published

wheneverの導入

gemfile
 # 下記をGemfileに追記
+ gem 'whenever'
terminal
# gemのインストール
bundle install
# wheneverの初期化
bundle exec wheneverize .
config/schedule.rb
 # ファイルが生成されるので、下記を設定する
+ require File.expand_path(File.dirname(__FILE__) + '/environment')
+ rails_env = ENV['RAILS_ENV'] || :development
 # cronを実行する環境変数をセット
+ set :environment, rails_env
 # cronのログの吐き出し場所
+ set :output, "#{Rails.root}/log/cron.log"

 # 10分ごとにrakeタスクを実行する
+ every 10.minutes do
+ rake 'change_state:change_published'
+ end

cronへ設定反映

terminal
# 設定を反映
bundle exec whenever
# cronタスクを確認
crontab -l
# 編集した設定を反映
bundle exec whenever --update-crontab
# cronからタスクを削除
bundle exec whenever --clear-crontab

参考サイト・資料

Udemyメディア:Rails scaffoldを初心者向けに解説!実際にアプリを作ってみよう!
Qiita:Railsでwheneverを使ってcronを設定する
Github:Whenever

Discussion