🐢
【Rails】投稿数の表示, 前日比・先週比の表示
本の投稿サイトに、投稿数、前日比・先週比の表示をさせます。
完成イメージ
実装要件
- 今日・前日の投稿数を表示
- 前日と今日の投稿数の差を表示
- 今週・先週の投稿数の合計を表示
- 今週と先週の投稿数の差を表示
モデル記述
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などの単体テストがしやすい)
- コントローラの可読性向上(コントローラがシンプルになる)
-
Time.zone.now.all_day
:今日作成されたレコードを取得。 -
1.day.ago.all_day
:前日に作成されたレコードを取得。 -
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
(現在の日時)が日付の終わりとなる。
-
-
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>
解説:
- 条件分岐:if文を使用して、前日の投稿数と先週の投稿数が0の場合にメッセージを表示します。これにより0のときのエラーを回避します。
- 数値計算:
-
@yesterday_book.count.to_f
:to_f
を使うと小数点表示ができます。 -
(@the_day_before * 100).round
:round
を使うと、小数点以下を四捨五入して整数にします。
-
以上、完成です。
続きはコチラ。
Discussion