この記事では、Railsアプリケーションで非同期的にテーブルを更新する方法について説明します。特に、スケジュール管理アプリケーションの例を用いて、特定の日付のスケジュールとその時間枠を動的に表示する方法を解説します。
1. 背景
スケジュール管理アプリケーションでは、ユーザーが日付を選択するたびに、該当日のスケジュールと時間枠を動的に表示する必要があります。この実装のためには、RailsサーバーからJSON形式でデータを取得し、フロントエンドでそのデータを使用してテーブルを更新する必要があります。
2. 実装の概要
2.1 サーバーサイド(Rails)
Railsのコントローラーで、選択された日付のスケジュールと時間枠を計算し、JSON形式で返すアクションを作成します。
2.2 クライアントサイド(JavaScript)
JavaScriptで、取得したJSONデータを使用してテーブルを動的に更新します。これには、テーブルのヘッダーとボディの両方を更新する処理が含まれます。
3. コードの詳細
3.1 Railsコントローラーの実装
まず、Railsのコントローラーでupdate_slots
アクションを定義します。このアクションでは、選択された日付に基づいてスケジュールと時間枠を計算し、それをJSON形式で返します。
# app/controllers/schedules_controller.rb
def update_slots
date = params[:date]
@date = Date.parse(date)
@company = current_company
@time_slots = generate_time_slots(@company)
Rails.logger.info "Generated Time Slots: #{@time_slots}"
@services = @company.services
@service_availability = ScheduleService.calculate_availability(@company, @date, @services, @time_slots)
response_data = {
services: @services.map { |service|
{
name: service.name,
duration: format_duration(service.duration),
time_slots: @time_slots.map { |slot| { availability: @service_availability[service.id][slot] } }
}
},
time_slots: @time_slots
}
Rails.logger.info "Response Data: #{response_data}" # 追加されたログ出力
render json: response_data
end
解説
-
generate_time_slots
メソッドで時間枠を生成します。 -
calculate_availability
メソッドで、各サービスの可用性を計算します。 -
response_data
としてサービス情報と時間枠をJSON形式で構築し、レスポンスとして返します。
3.2 JavaScriptでのテーブル更新
次に、JavaScriptで取得したJSONデータを使ってテーブルを更新します。
// app/javascript/controllers/application.js
function updateTable(data) {
console.log("Updating table with data:", data); // 受け取ったデータをログ出力
const tableHead = document.querySelector('.table-responsive thead');
const tableBody = document.querySelector('.table-responsive tbody');
tableHead.innerHTML = ''; // ヘッダーの内容をクリア
tableBody.innerHTML = ''; // ボディの内容をクリア
const headerRow = document.createElement('tr');
headerRow.innerHTML = `
<th class="sticky-left">サービス</th>
<th class="sticky-duration">所要時間</th>
`;
data.time_slots.forEach(slot => {
const th = document.createElement('th');
th.textContent = slot;
headerRow.appendChild(th);
});
tableHead.appendChild(headerRow);
data.services.forEach(service => {
let row = document.createElement('tr');
let nameCell = document.createElement('th');
nameCell.classList.add('service-name', 'sticky-left');
nameCell.textContent = service.name;
row.appendChild(nameCell);
let durationCell = document.createElement('th');
durationCell.classList.add('service-duration', 'sticky-duration');
durationCell.textContent = service.duration;
row.appendChild(durationCell);
service.time_slots.forEach(slot => {
let slotCell = document.createElement('td');
slotCell.textContent = slot.availability; // 各時間枠の可用性を表示
row.appendChild(slotCell);
});
tableBody.appendChild(row);
});
}
解説
-
updateTable
関数は、サーバーから取得したデータを使ってテーブルのヘッダーとボディを更新します。 - ヘッダー行を動的に生成し、時間枠を表示します。
- 各サービスの行を生成し、サービス名、所要時間、時間枠の可用性を表示します。
3.3 元のコードとの比較
元のRailsコントローラーコード
# app/controllers/schedules_controller.rb
def update_slots
date = params[:date]
@date = Date.parse(date)
@company = current_company
@services = @company.services
@time_slots = generate_time_slots(@company)
@service_availability = ScheduleService.calculate_availability(@company, @date, @services, @time_slots)
render json: {
services: @services.map do |service|
{
name: service.name,
duration: format_duration(service.duration),
time_slots: @time_slots.map do |slot|
{ availability: @service_availability[service.id][slot] }
end
end
}
}
end
元のJavaScriptコード
// app/javascript/controllers/application.js
function updateTable(data) {
// ここでテーブルの内容を更新
const tableBody = document.querySelector('.table-responsive tbody');
tableBody.innerHTML = ''; // 現在の内容をクリア
data.services.forEach(service => {
let row = `<tr>
<th class="service-name sticky-left">${service.name}</th>
<th class="service-duration sticky-duration">${service.duration}</th>`;
service.time_slots.forEach(slot => {
row += `<td>${slot.availability}</td>`;
});
row += '</tr>';
tableBody.innerHTML += row;
});
}
まとめ
この記事では、RailsとJavaScriptを使って非同期的にテーブルを更新する方法を紹介しました。サーバーサイドでデータをJSON形式で提供し、クライアントサイドでそのデータを使って動的にテーブルを更新する実装方法を詳しく解説しました。これにより、ユーザーが日付を変更するたびに、スケジュールと時間枠がリアルタイムで更新されるようになります。