🐢

【Rails】投稿数の表示, 前日比・先週比の表示

2023/10/11に公開

本の投稿サイトに、投稿数、前日比・先週比の表示をさせます。

完成イメージ

実装要件

  • 今日・前日の投稿数を表示
  • 前日と今日の投稿数の差を表示
  • 今週・先週の投稿数の合計を表示
  • 今週と先週の投稿数の差を表示

モデル記述

bookモデルにメソッドを記載する。

book.rb
scope :created_today, -> { where(created_at: Time.zone.now.all_day) } # 今日
scope :created_yesterday, -> { where(created_at: 1.day.ago.all_day) } # 前日
scope :created_this_week, -> { where(created_at: 6.day.ago.beginning_of_day..Time.zone.now.end_of_day) } #今週
scope :created_last_week, -> { where(created_at: 2.week.ago.beginning_of_day..1.week.ago.end_of_day) } # 先週

解説:
コントローラに書くこともできますが、MVC(Model-View-Controller)の観点から、モデルはデータベース関連のロジックを担当します。そのためモデルにロジックを作ることが適切です。モデルに書くと以下のメリットもあります。

  • コードを再利用できる(同じメソッドを複数の場所で使用できる)
  • テストが簡単(RSpecなどの単体テストがしやすい)
  • コントローラの可読性向上(コントローラがシンプルになる)
  1. Time.zone.now.all_day:今日作成されたレコードを取得。
  2. 1.day.ago.all_day:前日に作成されたレコードを取得。
  3. 6.day.ago.beginning_of_day..Time.zone.now.end_of_day
    • 6.day.ago:現在の日時から6日前の日時を計算
    • beginning_of_day:指定した日時をその日の始まりにする。つまり、6日前の日時をその週の初めとする。
    • end_of_day:指定した日時をその日の終わりに設定する。つまりtime.zone.now(現在の日時)が日付の終わりとなる。
  4. 2.week.ago.beginning_of_day..1.week.ago.end_of_day:2週間前から1週間前の終わりまで

scopeメソッドの使い方

scopeは、特定の条件に基づいてデータベースからレコードを抽出する際に使います。

scope :created_today, -> { ... }

上記のコードでは、:created_todayという名前のスコープを定義しています。

whereメソッドの使い方

whereは、指定された条件に一致するレコードをデータベースから抽出します。

コントローラ記述

今回はユーザー詳細ページに表示させるため、ユーザーコントローラから呼び出してあげます。

users_controller
  def show
   @books = @user.books
    @today_book =  @books.created_today
    @yesterday_book = @books.created_yesterday
    @this_week_book = @books.created_this_week
    @last_week_book = @books.created_last_week
  end

ビュー記述

users/show.html.erb
<h3>投稿数の前日比・先週比</h3>
<div class="table_container">
  <!-- 前日比のテーブル -->
  <table class="table table-bordered">
    <thead>
      <tr>
        <th>今日の投稿数</th>
        <th>前日の投稿数</th>
        <th>前日比</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td><%= @today_book.count %></td> <!-- 今日の投稿数を表示 -->
        <td><%= @yesterday_book.count %></td> <!-- 前日の投稿数を表示 -->
        <td>
          <% if @yesterday_book.count == 0 %>
            前日の投稿はありません
          <% else %>
            <% @the_day_before = @today_book.count / @yesterday_book.count.to_f %>
            <%= (@the_day_before * 100).round %>% <!-- 前日比を計算し、パーセントで表示 -->
          <% end %>
        </td>
      </tr>
    </tbody>
  </table>
</div>

<div class="table_container">
  <!-- 先週比のテーブル -->
  <table class="table table-bordered">
    <thead>
      <tr>
        <th>今週の投稿数</th>
        <th>先週の投稿数</th>
        <th>先週比</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td><%= @this_week_book.count %></td> <!-- 今週の投稿数を表示 -->
        <td><%= @last_week_book.count %></td> <!-- 先週の投稿数を表示 -->
        <td>
          <% if @last_week_book.count == 0 %>
            先週の投稿はありません
          <% else %>
            <% @the_week_before = @this_week_book.count / @last_week_book.count.to_f %>
            <%= (@the_week_before * 100).round %>% <!-- 先週比を計算し、パーセントで表示 -->
          <% end %>
        </td>
      </tr>
    </tbody>
  </table>
</div>

解説:

  1. 条件分岐:if文を使用して、前日の投稿数と先週の投稿数が0の場合にメッセージを表示します。これにより0のときのエラーを回避します。
  2. 数値計算:
    • @yesterday_book.count.to_f: to_fを使うと小数点表示ができます。
    • (@the_day_before * 100).roundroundを使うと、小数点以下を四捨五入して整数にします。

以上、完成です。

続きはコチラ。
https://zenn.dev/ganmo3/articles/39dea581126646

Discussion