開発環境
- ruby 2.6.3
- rails 6.0.2
あらすじ
- 【オプション課題1: 終了間近や期限の過ぎたタスクがあった場合、アラートを出したいという課題】を通して。
- 終了期限が切れたり、期限間際で通知するような仕組みを導入します。
通知モデルを作成
ターミナル
rails g model notification user:references task:references action:integer checked:boolean
db/migrate
class CreateNotifications < ActiveRecord::Migration[6.0]
def change
create_table :notifications do |t|
t.references :task, null: false, foreign_key: true
t.references :user, null: false, foreign_key: true
t.integer :action
t.boolean :checked, default: false, null: false
t.timestamps
end
end
end
- actionで通知の種類を分類し、checkedで未読、既読を識別する。
ターミナル
rails db:migrate
モデル各種
- taskの期限が近づいたり、過ぎたりで通知を出すのでtaskとnotificationは
1対1
です。
# Userモデル
app/models/user.rb
class User < ApplicationRecord
has_many :notifications, dependent: :destroy
end
Taskモデル
app/models/task.rb
class Task < ApplicationRecord
belongs_to :user
has_one :notification, dependent: :destroy
end
Notificationモデル
app/models/ntification.rb
class Notification < ApplicationRecord
default_scope->{order(created_at: :desc)}
belongs_to :task
belongs_to :user
enum action: { warning: 1, expired: 2}
end
enumとは
enum カラム名: {名前定義:数値}
列挙型であり実際に登録するときは名前定義の方をsaveします。
view側
- 一覧が確認できればいいのでindexのみです。
rails g controller notifications index
config/routes.rb
Rails.application.routes.draw do
resources :notifications,only: [:index]
end
app/controllers/notifications_controller.rb
class NotificationsController < ApplicationController
def index
@notifications = current_user.notifications
@notifications.where(checked: false).each do |notification|
notification.update(checked: true)
end
end
end
- indexにアクセスすると既読にさせます。
通知の未読、既読を知らせる
app/views/layouts/_header.html.slim
- if unchecked_notifications.any?
p.text-danger ★
= link_to "通知",notifications_path, class: 'nav-link'
app/helpers/notifications_heler.rb
module NotificationsHelper
def unchecked_notifications
@notifications = current_user.notifications.where(checked: false)
end
end
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
include NotificationsHelper
end
定期実行させるためにrakeタスクを作成
Rakeとは
そもそもRakeですが、Rubyで書かれたコードをタスクとして作成しておき必要に応じて呼び出し実行する事が出来る機能です。
rakeタスクを利用する場面としては、こんなのが有ります。
何かしらのデータの連携
データベースのバックアップ
定期的にデータを更新、削除する
オートロード対象となるパスの追加
についてはうまく行かなかったので直接rakeファイルに書きます。
rails g task notification
rails g task ファイル名
- 今日の日付からそれぞれの期限でDBをcreateさせていく。
lib/tasks/notification.rake
namespace :task do
desc "notification/一日に一回動かす。"
task :notification => :environment do
today = Date.today
tasks = Task.all
n = tasks.count
today = Date.today
tasks.each do |task|
user = task.user
if today + 1 == task.deadline.to_date
Notification.create(task_id: task.id, user_id: user.id, action: "warning")
end
if task.notification.nil? && today > task.deadline.to_date
Notification.create(task_id: task.id, user_id: user.id, action: "expired")
elsif task.notification.present? && today > task.deadline.to_date
task.notification.update(action: "expired")
end
n -= 1
puts "残り#{n}/#{tasks.count}"
end
end
end
実行
rake tasks:notification
rake [namespeceの名前]:[taskの名前]
本番環境に向けて
私の場合はherokuなのでheroku scheduler
を使うようです。
またまとめます。
gem:whenever
はcrontabに追記/書き換えしてくれてるgemです。
*WHENEVER勘違いしてたからHEROKUで動くわけなかった
【追記】heroku scheduler導入
-
Heroku Scheduler
1.heroku addons:add scheduler:standard
2.Heroku Scheduler上で実行したい時間とタスクを設定
heroku run rake task:notification