3
1

More than 3 years have passed since last update.

Wheneverを使用したタイムセール機能の実装(開発環境)

Posted at

はじめに

本記事は自分自身の備忘録として書いていますが、同じような実装を考えている方々の参考になればと思います。
また、私と同様、プログラミングを初めたばかりの方々向けに投稿していますので、できるかぎりシンプルに記載していきます!

※ runner以外のコマンドや crontab などの説明は本記事では割愛しています。

開発環境

Ruby : 2.5.1
Rails : 5.0.7.2
Whenever : 1.0.0

実現したいこと

ネットショップなどを想定して、出品中の商品全品を定期的に値下げしたい。
また、処理を自動で行いたい。

具体的に以下の1, 2を繰り返し実行したい。

  1. 毎週末(土日)に全商品が10%オフになる
  2. 毎月曜日に元値に戻す

実装の流れ

よくある、「週末は10%オフのセール!」みたいなやつを Whenever を使用して実装していきます。

前置き

まず、定期実行をする際に重宝するのが Whenever という Gem です。
タスクに登録して好きなタイミングで自動実行してくれます。
学習コストが低く、私のような初心者でも取っつきやすいのが特徴です!
Github: javan/whenever

本題

[1] タスクを作成する

必要なメソッドを備えた class や module が何処かにあれば良いと思いますが、今回は分かりやすく「lib/tasks」直下に「lib/tasks/product_task」ファイルを作成します。
また、このファイルに実行したい処理を記述します。

(lib/tasks/product_task.rb)
class Tasks::Product_task
  # 10%オフを実行するメソッド
  def self.set_time_sale
    Product.update_all("price =  price * 0.9")
  end

  # 10%オンを実行するメソッド
  def self.end_time_sale
    Product.update_all("price =  price / 0.9")
  end
end 

[2] タスクのパスをオートロードにする

Whenever から「lib/tasks」を呼び出せるようにパスを通す必要があります。
開発環境では config.autoload_paths 、本番環境では config.eager_load_paths が必要となります。

(config/application.rb)
module [アプリ名]
  class Application < Rails::Application

  (省略)

    config.autoload_paths   += Dir["#{config.root}/lib/**/"]
    config.eager_load_paths += Dir["#{config.root}/lib/**/"]
  end
end

[3] 手動で確認

ここで一度、設定ができているか確認をします。

(ターミナル)
$ bundle exec rails runner Tasks::Product_task.set_time_sale

動作問題なければタスクの設定は完了です!

[4] Whenever の導入

Gemfile に記述し、bundle install します。

(Gemfile)
gem 'whenever', :require => false

[5] Whenever の設定ファイルを作成

下記コマンドを打つと、「config/schedule.rb」が作成されます。
これがcrontabの元になり、「○曜日にxxを実行」みたいな処理をこのファイルに記述していきます。

(ターミナル)
$ bundle exec wheneverize

[6] schedule.rbの編集

先ほど作ったタスクを登録する為、以下のように記述します。

(config/schedule.rb)
require File.expand_path(File.dirname(__FILE__) + "/environment")

rails_env  = Rails.env.to_sym
rails_root = Rails.root.to_s

# デフォルトは本番環境になる為、明示的に開発環境を指定する
set :environment, rails_env
set :output, "#{rails_root}/log/cron.log"

# 毎週末にタスクで定義した set_time_sale を実行する
every :weekend do
  runner 'Tasks::Product_task.set_time_sale'
end

# 毎週月曜日にタスクで定義した end_time_sale を実行する
every :monday do
  runner 'Tasks::Product_task.end_time_sale'
end 

[7] crontabへ反映させる

(ターミナル)
$ bundle exec wheneverize

[write] crontab file updated がターミナル上に出てくれば登録完了です!

お疲れさまでした!

補足

今回の実装コードはあくまで、開発環境でのみ機能する仕様です。
本番環境は別途対応が必要になりますので、以下の記事などを参考にしてください。
一つ注意点としては、Herokuはサポートされていないみたいです。
もしHerokuで定期実行したいタスクがあるのなら「Heroku Scheduler」を活用しましょう。

Railsでwheneverを使ってcronを設定する

また、本実装はこのままでは問題点があります。。
月曜日に出品した商品は10%オンした状態になる為、修正が必要です。
内容については、実現したいことに合わせて書き換えてご活用ください。

参考記事

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1