記録アプリの機能を学ぼう
記録アプリの機能を学ぼう
1.ユーザ詳細ページに、今日の投稿数を表示させる
2.ユーザ詳細ページに、前日の投稿数を表示させる
3.ユーザ詳細ページに、前日と今日の投稿数の差を表示させる
4.ユーザ詳細ページに、今週の投稿数の合計を表示させる
5.ユーザ詳細ページに、先週の投稿数の合計を表示させる
6.ユーザ詳細ページに、今週と先週の投稿数の差を表示させる(先週と比べる)
必要なものを考えてみる
新しいテーブルは必要か?⇒いらない
「表示させる」だけなので、すでにあるモデルたちのリレーションをしっかりすればOK
⇒userのshowアクション内に投稿数を日付と紐づいた内容で習得し表示させる
以下は自分の書いたコード(運営の答えは異なる)
答えと違っていた言い訳
結論は簡単な方を採用したら違ってた
正直、今まで習った事だけで書くコードなら正解だと思う。
スコープの定義は答えのコードを見て、初めて知った機能。
考え方においては、新しいテーブルが不要だったのは正解だった。
もはや課題の出し方が不適切では・・・
考え方は合っていた。方法が違っていただけなので悲観することはないはず
def show
@user = User.find(params[:id])
today = Date.today
yesterday = today - 1
start_of_week = today.beginning_of_week
start_of_last_week = start_of_week - 1.week
@today_books_count = @user.books.where(created_at: today.all_day).count
@yesterday_books_count = @user.books.where(created_at: yesterday.all_day).count
@weekly_books_count = @user.books.where(created_at: start_of_week..today).count
@last_week_books_count = @user.books.where(created_at: start_of_last_week..start_of_week - 1.day).count
@difference_today_yesterday = @today_books_count - @yesterday_books_count
@difference_weekly = @weekly_books_count - @last_week_books_count
end
投稿したBookには日付のデータはcreated_atで最初から存在しているので、それをいじる感じ
ビューのコードは以下の通り
<p>今日の投稿数: <%= @today_posts_count %></p>
<p>前日の投稿数: <%= @yesterday_posts_count %></p>
<p>前日と今日の投稿数の差: <%= @difference_today_yesterday %></p>
<p>今週の投稿数の合計: <%= @weekly_posts_count %></p>
<p>先週の投稿数の合計: <%= @last_week_posts_count %></p>
<p>今週と先週の投稿数の差: <%= @difference_weekly %></p>
これで問題なく動いた。
(修正箇所を挙げるなら、データが無い時、つまり投稿が過去にされてないときは、何も表示されないので、そこに対応させたif文を用意しとくべき。それでコードが長くなり可読性が落ちるので、テンプレートを採用すべきだった。⇒でも、クライアントに本件の重要性や納期の背景が無かったので・・・コスパやタイパ意識しました。)
答え(追加分だけ記載する)
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) } # 前週
def show
//省略
@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
ここまで来たら、あとはビューのコードのみ!
<h3>投稿数の前日比・前週比</h3>
<div>
<p>今日の投稿数: <%= @today_book.count %> 件</p>
<p>前日の投稿数: <%= @yesterday_book.count %> 件</p>
<p>前日比:
<% if @yesterday_book.count == 0 %>
前日の投稿が0のため計算できません
<% else %>
<% @the_day_before = @today_book.count / @yesterday_book.count.to_f %>
<%= (@the_day_before * 100).round %>% 増加
<% end %>
</p>
</div>
<div>
<p>今週の投稿数: <%= @this_week_book.count %> 件</p>
<p>前週の投稿数: <%= @last_week_book.count %> 件</p>
<p>前週比:
<% if @last_week_book.count == 0 %>
前週の投稿が0のため計算できません
<% else %>
<% @the_week_before = @this_week_book.count / @last_week_book.count.to_f %>
<%= (@the_week_before * 100).round %>% 増加
<% end %>
</p>
</div>
テンプレートで作成しました
あとは<%= render 'book_index',books: @books %>をshowページに入れるだけ。
スコープってなんぞ?
scope
は、Railsのモデルでよく使われる便利な機能で、データベースから特定の条件に合致するレコードを簡潔に取得するための方法です。scope
を使うことで、クエリを簡潔に書けるだけでなく、再利用しやすくなり、コードの可読性も向上します。
基本的な構文
scope
は、モデルクラスで定義します。一般的な構文は以下の通りです。
scope :スコープ名, -> { 条件 }
-
スコープ名
:任意の名前で定義します。この名前を使ってスコープを呼び出します。 -
-> { 条件 }
:この部分に条件を記述します。where
やorder
などを使って、レコードを取得するための条件を定義します。
具体例
以下に、Book
モデルでいくつかのスコープを定義する例を示します。
class Book < ApplicationRecord
# 今日作成された本を取得するスコープ
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) }
end
スコープの使い方
スコープは、定義した名前を使って簡単に呼び出せます。例えば、Book
モデルで定義したcreated_today
スコープを使って、今日作成された本を取得するには次のように書きます。
@today_books = Book.created_today
スコープを組み合わせる
複数のスコープを組み合わせて使用することも可能です。例えば、published
というスコープとcreated_today
というスコープを持つ場合、以下のように組み合わせて使用できます。
@published_today_books = Book.published.created_today
これは、「公開されていて、今日作成された本」を取得するクエリになります。
スコープの利点
- クエリの再利用:同じ条件を何度も書く必要がなく、スコープとして定義することで再利用が簡単になります。
-
コードの可読性向上:
where
句や複雑なクエリを直接書く代わりに、スコープを使うことでコードが読みやすくなります。 - チェーン可能:スコープをチェーンして複数の条件を組み合わせたクエリを作成できます。
注意点
- スコープの中で使う条件は、基本的に
ActiveRecord::Relation
オブジェクトを返す必要があります。例えば、where
やorder
などのクエリメソッドが一般的です。 - 複雑なロジックを含むスコープには、ブロックの中で
if
文や変数を使って条件を分けることも可能です。
まとめ
scope
は、Railsのモデルでクエリを簡単に定義して再利用するための強力なツールです。シンプルなクエリから複雑なクエリまで対応でき、コードの管理と可読性を向上させることができます。
1.過去 7 日間分、それぞれの投稿数を一覧表示させる
2.chart.js を使って、過去 7 日分の投稿数グラフ化
chartの導入が必要
過去 7 日間分の投稿が必要。
⇒スコープの調整して-1-2-3..とやっていく、おそらくeach文で回数を指定して習得?
mapメソッド
正解は・・・eachメソッドは、要素を一つずつ取り出してブロックを実行するだけ
mapメソッドは、ブロックを実行した結果を新しい配列として返す
def show
//省略
# 過去7日間の投稿数を取得
@daily_books = (0..6).map do |i|
day = i.days.ago.to_date
{ date: day, count: @books.created_on(day).count }
end
スコープの調整も必要
scope :created_on, ->(date) { where(created_at: date.all_day) }
# 各日付ごとのスコープを追加
<h2>過去7日間の投稿数</h2>
<table class='table table-bordered'>
<thead>
<tr>
<th>6日前</th>
<th>5日前</th>
<th>4日前</th>
<th>3日前</th>
<th>2日前</th>
<th>1日前</th>
<th>今日</th>
</tr>
</thead>
<tbody>
<tr>
<% @daily_books.reverse_each do |day_info| %>
<td><%= day_info[:count] %></td>
<% end %>
</tr>
</tbody>
</table>
今回の間違いは、使用するメソッドを間違えていた点。
eachメソッドは、基本的に表示させたいときに使う
mapメソッドは、データの配列が欲しい時に使う
Chart.js を使用して過去 7 日分の投稿数をグラフ化する手順
1. Webpacker で Chart.js を導入
まず、Chart.js をインストールします。以下のコマンドを実行してください。
yarn add chart.js
2. コントローラーの修正
ユーザーの詳細を表示するコントローラーに、過去 7 日間の投稿データを取得する処理を追加します。
# app/controllers/users_controller.rb
def show
@user = User.find(params[:id])
# 省略...
@daily_books = (0..6).map do |i|
day = i.days.ago.to_date
{ date: day.strftime("%Y-%m-%d"), count: @user.books.created_on(day).count }
end
end
ここでは、日付とその日の投稿数を取得し、@daily_books
に格納しています。
date: day.strftime("%Y-%m-%d") の部分は、
Rubyの strftime メソッドを使用して日付を特定のフォーマットの文字列に変換しています。
この場合、"%Y-%m-%d" というフォーマット指定子が使われています。
3. ビューにグラフ用のキャンバスを追加
次に、グラフを表示するための <canvas>
タグをビューに追加します。
<!-- app/views/users/show.html.erb -->
<canvas id="daily-books-chart" width="400" height="200"></canvas>
<div id="daily-books-data" data-daily-books='<%= @daily_books.to_json %>'></div>
<div id="daily-books-data" data-daily-books='<%= @daily_books.to_json %>'></div>って?
このコードは、HTML要素を定義して、JavaScriptで利用するためのデータを埋め込んでいます。以下は、それぞれの部分についての説明です。
<div>
タグ
1. - 役割: HTMLの「ディビジョン(区切り)」を表すタグです。Webページ内のコンテンツを区分けするために使われます。
-
ここでの役割: この
<div>
タグは、日付とその日付に関連する本の数を格納するための特別なコンテナとして使われています。
id="daily-books-data"
2. -
役割:
id
属性は、その要素を一意に識別するための名前を指定します。 -
ここでの役割:
daily-books-data
という名前のid
が設定されていることで、JavaScriptからこの要素を簡単に取得し、操作できるようになります。
data-daily-books='<%= @daily_books.to_json %>'
3. -
役割:
data-
属性は、カスタムデータ属性を定義するために使います。HTML5では、data-
で始まる属性を使用することで、データをHTMLに埋め込むことができます。 -
ここでの役割:
-
data-daily-books
は、JavaScriptが利用するためのデータを格納するカスタム属性です。 -
<%= @daily_books.to_json %>
はRubyのコードで、@daily_books
という変数をJSON形式に変換し、その結果をHTMLに埋め込んでいます。これにより、JavaScriptで利用可能な形式のデータになります。
-
@daily_books
5. - 役割: Railsのインスタンス変数で、コントローラー内で定義されている変数です。この変数には、過去7日間の各日付とその日付に関連する本の数が格納されています。
- ここでの役割: ユーザーに関連する本の情報を格納している変数です。
to_json
6. - 役割: Rubyのメソッドで、オブジェクトをJSON(JavaScript Object Notation)形式の文字列に変換します。
-
ここでの役割:
@daily_books
に含まれるデータを、JavaScriptが扱いやすい形式に変換します。これにより、JavaScriptでデータを簡単に処理できるようになります。
まとめ
このコード全体は、過去7日間の本の情報を含むJSON形式のデータをHTMLの div
要素に埋め込み、JavaScriptからアクセスできるようにしています。これにより、ページが読み込まれた後にJavaScriptを使ってこのデータを取り出し、グラフなどを表示することが可能になります。
カスタム属性?
定義:
カスタム属性は、HTML要素に追加できる特別な属性で、data- で始まります。
これにより、開発者が自分で定義したデータをHTML要素に持たせることができます。
役割:
カスタム属性は、特定の要素に関連するデータを保持し、
JavaScriptから簡単にアクセスできるようにするために使用されます。
例えば、ある要素に関連する設定や状態を格納するのに便利です。
例: data-user-id="123" のようなカスタム属性があった場合、
JavaScriptでこの要素を取得して、element.dataset.userId とすることで
123 にアクセスできます。
JSON形式?
JSON形式
- 定義: JSON(JavaScript Object Notation)は、データを構造化して表現するためのフォーマットです。主に、オブジェクトや配列の形でデータを格納するのに使用されます。
- 役割: JSONは、サーバーとクライアント間でデータを送受信する際によく使われます。人間にもわかりやすく、また多くのプログラミング言語で簡単に扱えるため、非常に広く利用されています。
-
例: 以下はJSON形式のデータの例です。上記は、日付とその日に関連する本の数を表すオブジェクトです。
{ "date": "2024-10-28", "count": 5 }
<div id="daily-books-data" data-daily-books='<%= @daily_books.to_json %>'></div>
の文脈
-
この
div
要素は、data-daily-books
というカスタム属性を持っていて、ここに@daily_books
のデータがJSON形式で格納されています。具体的には、Railsのto_json
メソッドによって、@daily_books
の内容がJSON形式に変換され、その結果がHTMLのこの属性に挿入されます。 -
これにより、JavaScriptからはこの要素を参照し、
data-daily-books
属性にアクセスすることで、必要なデータ(本の数や日付の情報)を簡単に取得できるようになります。
4. Chart.js を使ってグラフを描画する JavaScript の作成
次に、Chart.js を使用してグラフを描画するための JavaScript コードを記述します。
// app/javascript/packs/daily_books_chart.js
import Chart from 'chart.js/auto';
document.addEventListener('turbolinks:load', () => {
const canvas = document.getElementById('daily-books-chart');
const dailyBooksDataDiv = document.getElementById('daily-books-data');
if (canvas && dailyBooksDataDiv) {
const ctx = canvas.getContext('2d');
const dailyBooksData = JSON.parse(dailyBooksDataDiv.dataset.dailyBooks);
// データを逆順に取得
const labels = dailyBooksData.map(data => data.date).reverse();
const counts = dailyBooksData.map(data => data.count).reverse();
// Chartのインスタンスを作成
new Chart(ctx, {
type: 'bar', // グラフの種類
data: {
labels: labels,
datasets: [{
label: '投稿数',
data: counts,
backgroundColor: 'rgba(75, 192, 192, 0.2)',
borderColor: 'rgba(75, 192, 192, 1)',
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
} else {
console.error('Canvasまたはデータ要素が見つかりません。');
}
});
application.js
に Chart.js をインポート
5. アプリケーション全体で Chart.js を使用するために、application.js
にインポートを追加します。
// app/javascript/packs/application.js
import Chart from 'chart.js/auto';
6. JavaScript ファイルの読み込み設定
ユーザーの詳細画面に JavaScript ファイルを読み込むように設定します。以下のコードをページの一番下に記入します。
<!-- app/views/users/show.html.erb -->
<%= javascript_pack_tag 'daily_books_chart' %>
1.ユーザ詳細ページに、指定した日の記録(投稿数)を非同期で表示させる
カレンダー入力で日付を指定して、対象の日の投稿数を非同期通信で表示させる
指定した日の記録(投稿数)を非同期で表示させるためのロードマップを作成します。この機能では、カレンダー入力で日付を選択し、その日の投稿数をAjaxを用いて非同期で表示します。
ロードマップ
1. カレンダー入力の追加
まず、ユーザ詳細ページにカレンダー入力を追加します。選択された日付を送信するフォームを作成します。
<!-- show.html.erb -->
<h2>指定日の投稿数を表示</h2>
<%= form_with url: check_daily_books_user_path(@user), method: :get, local: false, id: 'daily-books-form' do %>
<%= date_field_tag :date, Date.today, id: 'date-input' %>
<%= submit_tag '検索' %>
<% end %>
<div id="daily-books-result"></div>
local: falseになってることを確認する
ここで、check_daily_books_user_path
は日付指定による投稿数取得用のルートです
新しいルートが増えたなら、ルーティングの修正が必須⇓
2. ルートの設定
config/routes.rb
にルートを追加します。
resources :users do
member do
get 'check_daily_books'
end
end
member doの意味
memberブロックは、特定のリソースのIDを持つユーザーに対して行うアクションを定義します。
この場合は、特定のユーザーの情報に対して行う操作です。
使用例:
member do
get 'check_daily_books'
end
このコードにより、
特定のユーザーのIDに基づいてcheck_daily_booksアクションを呼び出すことが
できるようになります。たとえば、ユーザーIDが1のとき、次のようなURLが生成されます:
GET /users/1/check_daily_books
特定のユーザーの追加ぺージを作成したいときに使えるね
非同期なのにルーティングいるの?
⇒ルーティングはぺージ移動のためじゃない!コントローラーのアクションを呼ぶため!
⇒そのアクション内で非同期に対応した書き方(ぺージ移動)でれば大丈夫!
3. コントローラーの追加
UsersController
に新しいアクションを追加します。指定された日付に基づいて投稿数を取得し、非同期で結果を返します。
# users_controller.rb
def check_daily_books
@user = User.find(params[:id])
date = params[:date].to_date
@book_count = @user.books.created_on(date).count
respond_to do |format|
format.js
end
end
何してるん?
このコードは、特定のユーザーに対して指定された日付の投稿数を取得し、非同期で結果を返すためのcheck_daily_books
アクションをUsersController
に追加するものです。それぞれの部分を詳しく解説します。
def check_daily_books
1. def check_daily_books
-
何か: これは新しいアクションの定義です。
UsersController
の中で、特定の機能を持つメソッドを作成します。 - 目的: このアクションは、指定された日付に基づいてユーザーの投稿数を取得するために使用されます。
@user = User.find(params[:id])
2. @user = User.find(params[:id])
-
何か:
params[:id]
を使用して、URLから指定されたユーザーIDを取得し、そのIDに基づいてユーザーをデータベースから検索します。 -
目的: 取得したユーザーを
@user
というインスタンス変数に格納することで、他の部分(例えば、ビューやレスポンス)で利用できるようにします。
date = params[:date].to_date
3. date = params[:date].to_date
-
何か:
params[:date]
から日付情報を取得し、to_date
メソッドを使用して文字列を日付型に変換します。 - 目的: 正しい形式の日付を使用することで、その日付に基づいて投稿数を正確に取得できるようにします。
@book_count = @user.books.created_on(date).count
4. @book_count = @user.books.created_on(date).count
-
何か:
@user.books
でユーザーの投稿を取得し、created_on(date)
メソッドを使用して指定された日付に作成された投稿をフィルタリングします。その後、count
メソッドでその投稿の数を数えます。 -
目的: 指定された日付における投稿数を取得し、
@book_count
というインスタンス変数に保存します。これにより、後でビューで結果を表示できます。
respond_to do |format|
5. respond_to do |format|
- 何か: このブロックは、異なるフォーマットに応じたレスポンスを返すためのものです。
- 目的: このアクションがJavaScriptリクエストに応答することを示します。これにより、非同期的にデータを返すことが可能になります。
format.js
6. format.js
- 何か: JavaScript形式のレスポンスを指定します。
-
目的: このアクションがJSフォーマットでリクエストされたとき、
check_daily_books.js.erb
という名前のテンプレートを自動的に探し、そのテンプレートが実行されるようにします。これにより、非同期でクライアントにデータを返すことができます。
そのアクション名のjsファイルを探すようになるので作成する⇓
4. ビューに非同期通信用のJavaScriptテンプレートを作成
check_daily_books.js.erb
ファイルを作成して、非同期通信の結果を表示する処理を記述します。
document.getElementById('daily-books-result').innerHTML =
"<p>指定日の投稿数: <%= @book_count %>件</p>";
check_daily_books.js.erb
ファイルは、Railsの非同期通信(AJAX)によってサーバーから返された結果をクライアント側で処理するためのJavaScriptコードを含むテンプレートです。このファイルがどのように機能するのか、各要素を詳しく解説します。
コードの解説
document.getElementById('daily-books-result').innerHTML =
"<p>指定日の投稿数: <%= @book_count %>件</p>";
詳しい解説
-
document.getElementById('daily-books-result')
:-
説明: この部分は、HTMLドキュメント内の要素を取得するためのJavaScriptコードです。
getElementById
メソッドを使って、id
属性がdaily-books-result
の要素を取得します。 - 用途: 取得した要素は、非同期通信の結果を表示するための場所になります。つまり、この要素に投稿数を表示することを目的としています。
-
説明: この部分は、HTMLドキュメント内の要素を取得するためのJavaScriptコードです。
-
innerHTML
:-
説明:
innerHTML
は、HTML要素の内容を設定または取得するためのプロパティです。このプロパティを使用することで、要素の中身を動的に変更できます。 - 用途: ここでは、指定された要素の内容を、指定日の投稿数を含む新しいHTML内容に置き換えています。
-
説明:
-
"<p>指定日の投稿数: <%= @book_count %>件</p>"
:-
説明: この部分は、HTMLの文字列を生成しています。
<%= @book_count %>
は、Ruby on RailsのERB(Embedded Ruby)記法で、サーバーサイドで生成される@book_count
の値を埋め込むためのものです。 -
用途:
@book_count
は、指定された日付に対する投稿数で、コントローラーのアクション内で計算されています。この値が埋め込まれることで、実際に表示されるのは例えば「指定日の投稿数: 5件」となります。
-
説明: この部分は、HTMLの文字列を生成しています。
動作の流れ
- ユーザーが指定した日付に基づいて投稿数を取得するためのリクエストが送信されます。
-
UsersController
内のcheck_daily_books
アクションが呼び出され、指定された日付の投稿数を計算します。 - 結果(投稿数)を含む
check_daily_books.js.erb
テンプレートがサーバーから返されます。 - ブラウザは受け取ったJavaScriptコードを実行し、
daily-books-result
要素の内容を更新します。
5. JavaScriptでフォームの非同期通信を設定
カレンダー入力のフォームを送信する際、Ajaxを利用して非同期通信を行うように設定します。
document.addEventListener('DOMContentLoaded', () => {
const form = document.getElementById('daily-books-form');
form.addEventListener('ajax:success', (event) => {
const [data, status, xhr] = event.detail;
// check_daily_books.js.erbで処理されるため、ここでは特に処理は必要ない
});
form.addEventListener('ajax:error', () => {
alert('エラーが発生しました。');
});
});
コードの解説
-
document.addEventListener('DOMContentLoaded', () => { ... });
:-
説明:
DOMContentLoaded
イベントは、HTML文書の完全な読み込みが完了した時点で発火します。このイベントを使うことで、DOM要素にアクセスできる状態でJavaScriptコードを実行することができます。 - 用途: このイベントが発生すると、フォームに対して必要なイベントリスナーが設定されるので、DOMが完全に準備されてから実行されます。
-
説明:
-
const form = document.getElementById('daily-books-form');
:-
説明: この行では、HTML内の
id
がdaily-books-form
であるフォーム要素を取得し、form
変数に格納しています。 - 用途: この変数を使って、フォームに対するイベントリスナーを設定したり、フォームに関連する処理を行ったりします。
-
説明: この行では、HTML内の
-
form.addEventListener('ajax:success', (event) => { ... });
:-
説明: この行では、
ajax:success
イベントに対するリスナーを設定しています。これは、非同期通信が成功した際に発火するイベントです。 -
用途: 成功した際の処理を定義するための関数を提供します。ここでは、
event.detail
を使って成功した通信の詳細情報を取得し、データを使うことができます。ただし、このコードでは、check_daily_books.js.erb
ファイルで処理されるため、特に何も行っていません。
-
説明: この行では、
-
const [data, status, xhr] = event.detail;
:-
説明:
event.detail
は、成功した非同期通信の詳細な情報を含む配列です。これには、サーバーから返されたデータ(data
)、HTTPステータス(status
)、およびXHRオブジェクト(xhr
)が含まれます。 - 用途: これらの情報を取得することで、必要に応じてさらなる処理を行うことができますが、現在のコードでは特に使用されていません。
-
説明:
-
form.addEventListener('ajax:error', () => { ... });
:-
説明: これは、非同期通信が失敗したときに発火する
ajax:error
イベントに対するリスナーを設定する行です。 - 用途: 通信にエラーが発生した際に実行される処理を定義します。ここでは、アラートボックスを表示して「エラーが発生しました。」とユーザーに通知します。
-
説明: これは、非同期通信が失敗したときに発火する
6. テストと確認
- カレンダー入力で日付を選択し、「検索」ボタンを押したときに、指定日の投稿数が非同期で表示されるかを確認します。
- 必要に応じて、エラーメッセージやローディング表示を追加します。
ロードマップのまとめ
- カレンダー入力の追加: ユーザ詳細ページにカレンダー入力フォームを設置。
- ルートの設定: 日付指定による投稿数取得用のルートを追加。
- コントローラーの追加: 指定された日付に基づいて投稿数を取得するアクションを追加。
- 非同期通信用のJavaScriptテンプレート作成: 結果を表示するテンプレートを作成。
- JavaScriptの設定: フォームをAjaxで送信するための設定。
- テストと確認: 機能が期待通り動作するかをテスト。
これにより、ユーザ詳細ページで指定した日付の投稿数を非同期で表示できるようになります。