目標
開発環境
・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina
前提
下記実装済み。
・Slim導入
・Bootstrap3導入
・ログイン機能実装
・投稿機能実装
実装
1.カラムを追加
ターミナル
$ rails g model Coupon user_id:integer is_valid:boolean limit:integer
~__create_coupons.rb
class CreateCoupons < ActiveRecord::Migration[5.2]
def change
create_table :coupons do |t|
t.integer :user_id
t.boolean :is_valid, default: true # 「default: true」を追記
t.integer :limit
t.timestamps
end
end
end
ターミナル
$ rails db:migrate
2.モデルを編集
user.rb
# 追記
has_many :coupons, dependent: :destroy
coupon.rb
class Coupon < ApplicationRecord
belongs_to :user
enum is_valid: { '有効': true, '無効': false }
def self.coupon_create(user)
coupon = Coupon.new(user_id: user.id, limit: 1)
coupon.save
end
def self.coupon_destroy
time = Time.now
coupons = Coupon.all
coupons.each do |coupon|
if coupon.created_at + coupon.limit.days < time && coupon.is_valid == '有効'
coupon.is_valid = '無効'
coupon.save
end
end
end
end
【解説】
① クーポンの状態をenumで管理する。
enum is_valid: { '有効': true, '無効': false }
② クーポンを作成するメソッドを定義する。
def self.coupon_create(user)
coupon = Coupon.new(user_id: user.id, limit: 1)
coupon.save
end
③ クーポンを削除するメソッドを定義する。
def self.coupon_destroy
time = Time.now
coupons = Coupon.all
coupons.each do |coupon|
if coupon.created_at + coupon.limit.days < time && coupon.is_valid == '有効'
coupon.is_valid = '無効'
coupon.save
end
end
end
◎ クーポンを作成してから24時間経過かつ、クーポンの状態が有効の場合は、無効に変更して保存する。
if coupon.created_at + coupon.limit.minutes < time && coupon.is_valid == '有効'
coupon.is_valid = '無効'
coupon.save
end
3.coupons_controller.rb
を作成・編集
ターミナル
$ rails g controller coupons index
coupons_controller.rb
class CouponsController < ApplicationController
def index
@coupons = Coupon.where(user_id: current_user.id, is_valid: '有効')
end
end
4.books_controller.rb
を編集
今回は本を投稿成功した場合に、クーポンを発行するように実装します。
books_controller.rb
def create
@book = Book.new(book_params)
@book.user_id = current_user.id
if @book.save
Coupon.coupon_create(current_user) # 追記
redirect_to books_path
else
@books = Book.all
render 'index'
end
end
5.日時設定を変更
①application.rb
を編集する。
application.rb
module Bookers2Debug
class Application < Rails::Application
config.load_defaults 5.2
config.time_zone = 'Tokyo' # 追記
end
end
②日時のフォーマットを設定するファイルを作成・編集
ターミナル
$ touch config/initializers/time_formats.rb
time_formats.rb
Time::DATE_FORMATS[:datetime_jp] = '%Y/%m/%d/%H:%M'
6.ビューを編集
coupons/index.html.slim
.row
.col-xs-3
.col-xs-6
table.table
thead
tr
th
| クーポン番号
th
| タイトル
tbody
- @coupons.each.with_index(1) do |coupon, index|
tr
td
= index
td
- limit = coupon.created_at + coupon.limit.minutes
= limit.to_s(:datetime_jp)
.col-xs-3
【解説】
① クーポン作成日時の1日後を、5
で設定したフォーマットで表示する。
- limit = coupon.created_at + coupon.limit.minutes
= limit.to_s(:datetime_jp)
7.自動削除機能の実装
① Gemを導入
Gemfile
# 追記
gem 'whenever', require: false
ターミナル
$ bundle
② 「schedule.rb」
を作成・編集
ターミナル
$ bundle exec wheneverize .
config/schedule.rb
env :PATH, ENV['PATH'] # 絶対パスから相対パス指定
set :output, 'log/cron.log' # ログの出力先ファイルを設定
set :environment, :development # 環境を設定
every 1.minute do
runner 'Coupon.coupon_destroy'
end
###4.cron
を反映
ターミナル
$ bundle exec whenever --update-crontab
バッチ処理でよく使うコマンド
crontab -e
➡︎ cronをターミナル上で編集
$ bundle exec whenever
➡︎ cronの設定を確認
$ bundle exec whenever --update-crontab
➡︎ cronを反映
$ bundle exec whenever --clear-crontab
➡︎ cronを削除