[RUBY] [Rails] Implementation of coupon function (with automatic deletion function using batch processing)

Target

ezgif.com-video-to-gif (1).gif

Development environment

・ Ruby: 2.5.7 Rails: 5.2.4 ・ Vagrant: 2.2.7 -VirtualBox: 6.1 ・ OS: macOS Catalina

Premise

The following has been implemented.

Slim introductionIntroduction of Bootstrap3 -Login function implementationImplementation of posting function

Implementation

1. Add column

Terminal


$ 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:Added "true"
      t.integer :limit

      t.timestamps
    end
  end
end

Terminal


$ rails db:migrate

2. Edit the model

user.rb


#Postscript
has_many :coupons, dependent: :destroy

coupon.rb


class Coupon < ApplicationRecord
  belongs_to :user

  enum is_valid: { 'Effectiveness': true, 'Invalid': 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 == 'Effectiveness'
        coupon.is_valid = 'Invalid'
        coupon.save
      end
    end
  end
end

[Explanation]

① Manage the coupon status with enum.

enum is_valid: { 'Effectiveness': true, 'Invalid': false }

(2) Define a method to create a coupon.

def self.coupon_create(user)
  coupon = Coupon.new(user_id: user.id, limit: 1)
  coupon.save
end

③ Define a method to delete the coupon.

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 == 'Effectiveness'
      coupon.is_valid = 'Invalid'
      coupon.save
    end
  end
end

** ◎ If 24 hours have passed since the coupon was created and the coupon status is valid, change it to invalid and save it. ** **

if coupon.created_at + coupon.limit.minutes < time && coupon.is_valid == 'Effectiveness'
  coupon.is_valid = 'Invalid'
  coupon.save
end

3. Create / edit coupons_controller.rb

Terminal


$ rails g controller coupons index

coupons_controller.rb


class CouponsController < ApplicationController
  def index
    @coupons = Coupon.where(user_id: current_user.id, is_valid: 'Effectiveness') 
  end
end

4. Edit books_controller.rb

This time, we will implement a coupon to be issued when the book is posted successfully.

books_controller.rb


def create
  @book = Book.new(book_params)
  @book.user_id = current_user.id
  if @book.save
    Coupon.coupon_create(current_user) #Postscript
    redirect_to books_path
  else
    @books = Book.all
    render 'index'
  end
end

5. Change the date and time settings

① Edit ʻapplication.rb`.

application.rb


module Bookers2Debug
  class Application < Rails::Application
    config.load_defaults 5.2
    config.time_zone = 'Tokyo' #Postscript
  end
end

(2) Create / edit a file to set the date and time format

Terminal


$ touch config/initializers/time_formats.rb

time_formats.rb


Time::DATE_FORMATS[:datetime_jp] = '%Y/%m/%d/%H:%M'

6. Edit the view

slim:coupons/index.html.slim


.row
  .col-xs-3

  .col-xs-6
    table.table
      thead
        tr
          th
            |Coupon number
          th
            |title

      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

[Explanation]

(1) Display one day after the coupon creation date and time in the format set in 5.

- limit = coupon.created_at + coupon.limit.minutes
= limit.to_s(:datetime_jp)

7. Implementation of automatic deletion function

① Introduce Gem

Gemfile


#Postscript
gem 'whenever', require: false

Terminal


$ bundle

② Create and edit " schedule.rb "

Terminal


$ bundle exec wheneverize .

config/schedule.rb


env :PATH, ENV['PATH'] #Specify a relative path from an absolute path
set :output, 'log/cron.log' #Set the log output destination file
set :environment, :development #Set environment

every 1.minute do
  runner 'Coupon.coupon_destroy'
end

4. Reflect cron

Terminal


$ bundle exec whenever --update-crontab

Commands often used in batch processing

crontab -e ➡︎ Edit cron on the terminal

$ bundle exec whenever ➡︎ Check cron settings

$ bundle exec whenever --update-crontab ➡︎ Reflect cron

$ bundle exec whenever --clear-crontab ➡︎ Remove cron

Recommended Posts

[Rails] Implementation of coupon function (with automatic deletion function using batch processing)
[Rails] Implementation of batch processing using whenever (gem)
[Rails] Implementation of search function using gem's ransack
[Rails 6] Implementation of inquiry function using Action Mailer
[Rails] Implementation of image enlargement function using lightbox2
[Rails] Implementation of drag and drop function (with effect)
[Rails 6] Implementation of search function
[Rails] Implementation of multi-layer category function using ancestry "Preparation"
[Rails] Implementation of category function
[Rails] Implementation of multi-layer category function using ancestry "seed"
Login function implementation with rails
[Rails] Implementation of tutorial function
[Rails] Implementation of like function
[Rails] Implementation of multi-layer category function using ancestry "Editing form"
[Rails] Implementation of automatic address input using jpostal and jp_prefecture
[Rails] Implementation of multi-layer category function using ancestry "Creation form"
[Rails] Implementation of tagging function using intermediate table (without Gem)
[Rails] Implementation of user logic deletion
[Rails] Implementation of CSV import function
[Rails] Asynchronous implementation of like function
[Rails] About implementation of like function
[Rails] Implementation of user withdrawal function
[Rails] Implementation of CSV export function
[Rails] Implementation of new registration function in wizard format using devise
[Rails] Implementation of tag function using acts-as-taggable-on and tag input completion function using tag-it
Implementation of user authentication function using devise (2)
[Rails] Implementation of multi-layer category function using ancestry "I tried to make a window with Bootstrap 3"
Implementation of user authentication function using devise (1)
Rails [For beginners] Implementation of comment function
[Rails 6] Implementation of SNS (Twitter) sharing function
Implementation of user authentication function using devise (3)
[Vue.js] Implementation of menu function Implementation version rails6
[Ruby on rails] Implementation of like function
[Vue.js] Implementation of menu function Vue.js introduction rails6
[Rails] I will explain the implementation procedure of the follow function using form_with.
Implementation of Ruby on Rails login function (Session)
[Rails] Implementation of retweet function in SNS application
Ruby on Rails Email automatic sending function implementation
[Rails] Implementation of PV number ranking using impressionist
[Rails] Implementation of image slide show using Bootstrap 3
[Note] Summary of rails login function using devise ①
[Rails] Set validation for the search function using Rakuten API (from the implementation of Rakuten API)
Ruby on Rails <2021> Implementation of simple login function (form_with)
How to make batch processing with Rails + Heroku configuration
[Rails] Test of star evaluation function using Raty [Rspec]
Implementation of Ruby on Rails login function (devise edition)
Implementation of search function
[Ruby on Rails] Implementation of tagging function/tag filtering function
Using PAY.JP API with Rails ~ Implementation Preparation ~ (payjp.js v2)
Rails search function implementation
Implementation of pagination function
[Rails] Implementation of SNS authentication (Twitter, Facebook, Google) function
Control the processing flow of Spring Batch with JavaConfig.
Rails CRUD function implementation ① (new addition, deletion this time)
About merge processing implementation including sorting function of Stream API
Ruby on Rails Email automatic sending function setting (using gmail)
Be careful of initialization timing when using MessageEncryptor with Rails 5.2 / 6.0
Rails sorting function implementation (displayed in order of number of like)
[Rails] Implement event end function (logical deletion) using paranoia (gem)
[Rails] I tried to implement batch processing with Rake task
Rails implementation of ajax removal