LoginSignup
0
0

More than 1 year has passed since last update.

【Rails】制限時間機能を実装してみた。(解説付き)

Last updated at Posted at 2023-01-30

1.バージョンを確認しましょう!

Rails 5.1.6
ruby 2.7.2p112

2.完成イメージ

投稿に制限時間を設定し、何かしらの処理をつける機能です。
今回は 「投稿(タスク)を設定し、制限時間を超えると通知が来る機能」 を実装する準備段階です。

3.実装の大きな流れ

1.投稿モデル(Tweet)に、制限時間を保存するカラムを追加する。
2.投稿を保存するときに、制限時間と現在時刻を比較して、制限時間が過ぎていないかをチェックするアルゴリズムを記入する。
3.制限時間が過ぎている場合はエラーを返し、投稿を保存しない設定を仕込む。

ちなみに本記事はこのような目次で進んで行きます!
一緒に楽しんでいきましょう ᕙ( ˙꒳​˙ )ᕗ

4. モデルに、制限時間を保存するカラムを追加しよう。

$ rails generate migration AddLimitTimeToTweets limit_time:datetime
$ rails db:migrate

tweetsテーブルに、limit_timeというカラムを追加しました。
データ型は日時の保存に適しているdatetime型を採用しています。

多分マイグレーションファイルはこんな感じ。(一例)

~~_create_groups.rb
class AddLimitTimeToTweets < ActiveRecord::Migration[6.1]
  def change
    add_column :tweets, :limit_time, :datetime
  end
end

5.アルゴリズムを仕込む。

制限時間についてのアルゴリズムを仕込みましょう。
この記述がないと、現在時間よりも以前の時間で制限を設けることができ、サイトとして破綻してしまいます。

下記のモデルをこんな感じで編集していきましょう ᕙ( ˙꒳​˙ )ᕗ

app/models/tweet.rb
class Tweet < ApplicationRecord

  #追加

  validate :check_limit_time, on: :create
  validate :check_limit_time, on: :update

  private
  def check_limit_time
    if limit_time.present? && limit_time < Time.now
      errors.add(:limit_time, "制限時間を過ぎています")
    end
  end
end

コードの確認を初めます。先にprivateの中身から。

1) if limit_time.present? && limit_time < Time.nowの説明

まずcheck_limit_timeというメソッドを作っています。これはどんな処理でしょうか。
if A && Bは、AかつBの条件が成り立つ際に処理を実行しますという条件分岐文です。

この場合、Aはlimit_time.present?ですね。
これは、limit_timeという変数が存在するかどうかを確認するコードです。

Bは、limit_time < Time.nowです。
今の時間よりも、以前の場合ということですね。

つまり、現在は1月23日10:00なのに、1月23日8:00に制限を設定してしまったというようなイメージです。
論理的に破綻していますね。
 
 

2) errors.add(:limit_time, "制限時間を過ぎています")の説明

このような場合には、 errors.add(:limit_time, "制限時間を過ぎています")という処理を実行します。これは「制限時間を過ぎています」という警告を表示するコードですね。
 
 

3) validatesの説明

Validatesは、データベースに保存する前に、入力されたデータが正しいかどうかをチェックする機能です。
例えば、以下のように、emailカラムが必須であることをチェックする検証を追加することができます。

app/models/user.rb
class User < ApplicationRecord
  validates :email, presence: true
end

validationによって入力されたデータが正しくない場合は、保存されず、エラーを返すことができます。よって、データベースに不正なデータが保存されないようにすることができ、アプリケーションの信頼性を高めることができます。

今回は「投稿作成時」と、「投稿更新時」に確認を行いたいので、それぞれにcreateとupdateを仕込んでいます。

6.制限時間と現在時刻を比較して、タイムリミットを表示させる。

Viewファイルに下記のコードを追加しましょう✊

app/views/tweets/show.html.erb
  <% if @tweet.limit_time.present? && @tweet.limit_time > Time.now %>
      <div class="timer">
        <%= distance_of_time_in_words(@tweet.limit_time, Time.now) %>
      </div>
  <% end %>

ここでのif文は先ほどと同様のものです。割愛しますね。

ここではdistance_of_time_in_wordsというメソッドを使っています。
これは第一引数(@tweet.limit_time)と、
第二引数(Time.now)の時刻の間隔を、「xx分前」や「yy時間前」といった文字列に変換するものです。

ここで計算が行われることで、◯◯分前という表示を出すことに成功しました。

7.まとめ

そこまで複雑な機能設計はないので、もっと複雑なものを実装次第Qiitaに取り入れようと思っております。
タイマーかっこいい感じで表示したいなあ。少しがんばります。

0
0
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
0
0