14
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【rails】通知機能

Last updated at Posted at 2020-06-17

開発環境

  • 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
14
19
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
14
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?