目的
シンプルなブログアプリに記事のステータスを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