Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

付録G 完成版サンプルアプリのコード解説

本書を通して育てた Relay の全体像を、ファイルの役割と、対応する章で振り返ります。各部分が「どの章で、なぜそう作ったか」を、まとめて見渡せます。

モデル

ファイル役割
app/models/user.rbログインユーザー。担当タスク・コメントを持つ第5章
app/models/project.rbタスクをまとめる単位第5章
app/models/task.rb中心リソース。status enum、broadcasts_to第5章第18章
app/models/comment.rb / tag.rb / tagging.rbコメント・タグ(中間モデル含む)第5章

Task#status の enum(todo / in_progress / done)は、検索・絞り込み・バリデーション・表示の軸になりました(第4章)。

コントローラ

app/controllers/tasks_controller.rb が中心です。

  • index … 検索・絞り込み(sanitize_sql_like)、ページネーション、一覧スコープ @tasks第23章第24章第17章)。
  • create / update / destroy … 成功は redirect / Turbo Streams、失敗は 422(第8章第16章)。format.turbo_streamformat.html の両方を持つ。

認可は controller で行います(第31章)。Relay は単一チーム前提なので最小限です。

ビューと partial

ファイル役割
app/views/tasks/_task.html.erbタスク 1 件の表示(turbo_frame_tag第12章
app/views/tasks/_tasks.html.erb一覧領域(空状態の分岐込み)第17章
app/views/tasks/_form.html.erbフォーム(a11y 属性)第25章
app/views/tasks/*.turbo_stream.erbcreate / destroy などの stream 命令第16章
app/views/layouts/_flash.html.erbフラッシュ(#flash / aria-live第27章

partial を一覧と stream で共通化したのが、設計の要でした(第12章第17章)。

Stimulus controller

ファイル役割
autofocus_controller.js要素にフォーカス(エラーサマリにも再利用)第19章第25章
counter_controller.js文字数カウンタ第20章
toast_controller.jsトーストの自動消滅・閉じる(Values の delay)第21章第27章
search_controller.js入力の debounce 送信第23章
infinite_scroll_controller.jsIntersectionObserver で自動読み込み第24章
dropdown_controller.js / modal_controller.jsドロップダウン・モーダル第26章
chart_controller.js など外部ライブラリ連携第22章

どれも connect / disconnect を対にし、状態は HTML 側に置きました(第6部)。

リアルタイム

  • turbo_stream_from(購読、ログイン時のみ)と broadcasts_to / broadcast_*_to(配信)でリアルタイム更新(第18章第27章)。
  • 配信範囲と認可に注意(第31章)。

読み進め方

このアプリは、第2部で素の CRUD を作り、第3部以降で 1 つずつ Hotwire 化したものです。各ファイルを見るときは、対応する章に戻ると、「なぜそう書いたか」がたどれます。最初の素の状態から、段階を追って育てたことが、コード全体に表れています。

完成版の Relay のコード一式は、次のリポジトリで公開しています。

手元のコードと突き合わせながら読むと、各章の差分が追いやすくなります。