はじめに
今回は、前回の記事で実装した中の苦戦した場所などを記載します。
実装をしている記事は、前回書いていますので、
確認お願いします。
Point
routes
今回は、calenderの登録したイベントをクリックしてイベントの詳細を見るshowアクションとcalenderの日付の詳細を見るdate_detailsがURLの構造が似ている?のでエラーが出ました。
showアクション(events/:id)
date_detailsアクション(events/dates/:date)
resources :eventsの中にget "events/dates/:date"を入れずに外で定義するとエラーを回避できました。
get "events/dates/:date", to: "events#date_details", as: "event_date"
indexアクション
def index
@events = Event.all
respond_to do |format|
format.html
format.json do
render json: @events.map { |event|
{
id: event.id,
title: event.title,
start: event.time.in_time_zone("Asia/Tokyo").iso8601, # タイムゾーンを変換して送信
url: event_path(event)
}
}
end
end
end
respond_toでHTMLリクエストとJSONリクエストで異なるレスポンスを返すように。
HTMLレスポンス
format.html
特に何も指定していないので、Railsが自動で適切なviewを返す。(デフォルト:idnex.html.erb)
JSONレスポンス
format.json do
render json: @events.map { |event|
{
id: event.id,
title: event.title,
start: event.time.in_time_zone("Asia/Tokyo").iso8601,
url: event_path(event)
}
}
end
JSON形式のリクエストが来た場合に@eventsの内容をJSON形式で返すための処理
どのように設定しているか↓
- id: イベントのID
- title: イベントのタイトル
- start: イベントの時間をTokyoのタイムゾーンに
- uer: イベントの詳細リンク(showアクション)
start:event.time.in_time_zone("Asia/Tokyo").iso8601
こちらでUTC(協定世界時)からTokyoのタイムゾーンに変換してからISO 8601形式に整形している
start:event.time.in_time_zone("Asia/Tokyo").iso8601
- event.time:
データベースから取得されたUTC(協定世界時)形式の日時が格納されている - in_time_zone
ActiveSupportのメソッドで、日時オブジェクトのタイムゾーンを変換する - "Asia/Tokyo"
指定することで、UTCからTokyoのタイムゾーンに変換 - iso8601
最後に、iso8601メソッドを呼び出して、日時オブジェクトをISO 8601形式の文字列に変換している。この形式は、国際的に標準化された日時の表現方法で、例えば2023-10-01T10:00:00+09:00のような形式になる。
ISO 8601形式は、機械可読性が高く、異なるシステム間でのデータ交換に適しているため、APIなどでよく使われる
Javascript
インポート
import { Controller } from "@hotwired/stimulus";
Stimulusのコントローラーをインポートしている。これにより、DOM要素とJavaScriptのロジックを結びつけることができる
import { Calendar } from "@fullcalendar/core";
FullCalendarのコア機能をインポートしている。これを使ってカレンダーを作成する
import dayGridPlugin from "@fullcalendar/daygrid";
月表示のカレンダーを実現するためのプラグイン
import interactionPlugin from "@fullcalendar/interaction";
ユーザーが日付をクリックしたり、ドラッグしたりするインタラクションを実装するためのプラグイン
import jaLocale from "@fullcalendar/core/locales/ja";
日本語ロケールをインポートして、カレンダーの表示を日本語にする
plugins: [dayGridPlugin, interactionPlugin], #使用するプラグインを指定
initialView: 'dayGridMonth', #初期表示を「月」ビューに設定
timeZone: 'Asia/Tokyo', #タイムゾーンをTokyoに設定
locale: jaLocale, #カレンダーの言語を日本語に設定
events: '/events.json', #イベントデータを取得するAPIエンドポイントを指定
selectable: true, #日付を選択できるように設定
editable: true, #イベントを編集できるようにしている。
dateClick: (info) => { ###日付がクリックされた際の動作を定義
const date = new Date(info.date).toISOString().split("T")[0];
window.location.href = `/events/dates/${date}`;
},
クリックした日付をUTC基準のISO形式に変換し、日付部分のみを取得。
こちらをしないと本番環境でなぜか登録したイベントの表示がずれてしまう。
例)12/12にイベント登録をして12/12をクリックしても表示されない。12/11に表示されている。
取得した日付を使って、新しいURLにリダイレクトしている。これにより、特定の日付のイベントページに遷移する
終わり
初めてのcalenderの実装で色々苦戦しました