LoginSignup
0
0

RailsとJavaScriptを使った非同期テーブル更新の実装

Posted at

この記事では、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形式で提供し、クライアントサイドでそのデータを使って動的にテーブルを更新する実装方法を詳しく解説しました。これにより、ユーザーが日付を変更するたびに、スケジュールと時間枠がリアルタイムで更新されるようになります。

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