📑

ツール作成ロードマップ

2025/01/28に公開
1

MatchPath 開発ロードマップ(Rails 7 & Bootstrap 5対応) 完全版

このロードマップは、Rails 7 の最新バージョンに適用し、Bootstrap 5 を導入した大会管理システムの構築手順を網羅した完全版です。


1. Rails プロジェクトの初期セットアップ

1.1. プロジェクト作成

  1. 作業ディレクトリへ移動

    cd ~/projects
    mkdir matchpath && cd matchpath
    
  2. Rails プロジェクトの作成

    rails new . -d postgresql --css=bootstrap
    

    --css=bootstrap オプションを付けることで、Rails 7 の Import Maps 経由で Bootstrap を導入します。

  3. データベースの作成

    rails db:create
    

2. Bootstrap 5 の設定

2.1. Bootstrap を Import Maps で使用する

Import Maps に Bootstrap を追加:

bin/importmap pin bootstrap

2.2. Bootstrap の JavaScript を設定

app/javascript/application.js を編集:

import "bootstrap"

2.3. Bootstrap の CSS を適用

app/assets/stylesheets/application.bootstrap.scss を作成:

@import "bootstrap";

config/importmap.rb に以下を追加:

pin "bootstrap", to: "https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"

3. ユーザー管理機能

3.1. Devise のセットアップ

bundle add devise
rails generate devise:install

3.2. User モデルの作成

rails generate devise User

マイグレーションファイル (db/migrate/YYYYMMDD_devise_create_users.rb) に以下を追加:

t.string :name, null: false, default: ""
t.boolean :admin, default: false

マイグレーションを実行:

rails db:migrate

3.3. ユーザー登録フォームのカスタマイズ

rails generate devise:views

app/views/devise/registrations/new.html.erbedit.html.erbname 入力フィールドを追加:

<div class="mb-3">
  <%= f.label :name, class: "form-label" %>
  <%= f.text_field :name, class: "form-control", autofocus: true %>
</div>

3.4. Devise のストロングパラメータ

app/controllers/application_controller.rb:

class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
    devise_parameter_sanitizer.permit(:account_update, keys: [:name])
  end
end

4. トップページの作成

4.1. Home Controller の作成

rails generate controller Home index

4.2. ルーティング

config/routes.rb を修正:

Rails.application.routes.draw do
  root "home#index"
  
  devise_for :users
  
  namespace :admin do
    get "/", to: "admin#index", as: "index"
    resources :users, only: [:index]
  end

  resources :tournaments
  get "dashboard", to: "dashboard#index"
  resources :users, only: [:show]
  resources :matches, only: [:edit, :update]
end

4.3. Homeビュー

app/views/home/index.html.erb:

<h1>MatchPathへようこそ</h1>
<p>スイスドロー方式の大会を管理するツールです。</p>

<% if user_signed_in? %>
  <p>ようこそ、<%= current_user.name %> さん!</p>
  <%= link_to "ダッシュボード", dashboard_path, class: "btn btn-primary" %>
<% else %>
  <%= link_to "ログイン", new_user_session_path, class: "btn btn-success" %>
  <%= link_to "新規登録", new_user_registration_path, class: "btn btn-primary" %>
<% end %>

5. 管理者機能

5.1. 管理者の作成

Rails コンソールで管理者を作成:

rails console
User.create!(email: "admin@example.com", password: "password", password_confirmation: "password", admin: true)

5.2. 管理者エリアの作成

app/controllers/admin_controller.rb:

class AdminController < ApplicationController
  before_action :authenticate_user!
  before_action :check_admin

  def index
    @users = User.all
  end

  private

  def check_admin
    redirect_to root_path, alert: "管理者のみアクセス可能" unless current_user.admin?
  end
end

6. その他のページの追加

6.1. エラーページ

Rails の public/ にある 404.html500.html をカスタマイズ。

6.2. フッター

共通レイアウトの app/views/layouts/application.html.erb の最下部に追加:

<footer class="footer bg-light text-center py-3">
  <p>© 2025 MatchPath. All rights reserved.</p>
</footer>

7. 最終確認とデプロイ

7.1. ローカルでの確認

rails s

ブラウザで http://localhost:3000 にアクセスし、動作を確認。

7.2. デプロイ

Heroku 例:

git init
git add .
git commit -m "Initial commit"
heroku create matchpath
git push heroku main
heroku run rails db:migrate
heroku open

8. 今後の改善ポイント

  • 大会結果のエクスポート機能
  • 通知機能(試合開始のリマインダー)
  • リアルタイムスコア表示(ActionCable)
  • API化してモバイルアプリ対応

このロードマップを実行すれば、Rails 7 + Bootstrap 5 環境でスイスドロー方式の大会管理システムを完成させることができます! 🚀

Discussion

かいかい

以下は「MatchPath」で必要となるすべてのビューのコードを記載しています。各ページを網羅的にカバーしており、レスポンシブデザインとゲーム風の要素を考慮しています。


1. アプリケーションレイアウト

全ページで共通するレイアウト。

app/views/layouts/application.html.erb

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <title>MatchPath</title>
  <%= csrf_meta_tags %>
  <%= csp_meta_tag %>
  <%= stylesheet_link_tag "application", media: "all", "data-turbo-track": "reload" %>
  <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
  <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" rel="stylesheet">
</head>
<body>
  <nav class="navbar navbar-expand-lg navbar-light bg-light">
    <div class="container">
      <a class="navbar-brand" href="/">MatchPath</a>
      <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarNav">
        <ul class="navbar-nav ms-auto">
          <li class="nav-item"><%= link_to "ホーム", root_path, class: "nav-link" %></li>
          <% if user_signed_in? %>
            <li class="nav-item"><%= link_to "大会一覧", tournaments_path, class: "nav-link" %></li>
            <li class="nav-item"><%= link_to "プロフィール", edit_user_registration_path, class: "nav-link" %></li>
            <li class="nav-item"><%= link_to "ログアウト", destroy_user_session_path, method: :delete, class: "nav-link" %></li>
          <% else %>
            <li class="nav-item"><%= link_to "ログイン", new_user_session_path, class: "nav-link" %></li>
            <li class="nav-item"><%= link_to "サインアップ", new_user_registration_path, class: "nav-link" %></li>
          <% end %>
        </ul>
      </div>
    </div>
  </nav>
  <main class="container my-4">
    <%= yield %>
  </main>
  <footer class="text-center bg-light py-3 mt-5">
    <p>&copy; 2025 MatchPath. All rights reserved.</p>
  </footer>
</body>
</html>

2. トップページ

サイトの概要を表示し、ログイン・サインアップへの導線を提供。

app/views/home/index.html.erb

<div class="text-center">
  <h1>MatchPath</h1>
  <p>スイスドロー方式の大会管理ツールへようこそ!</p>
  <% if user_signed_in? %>
    <%= link_to "大会一覧を見る", tournaments_path, class: "btn btn-primary btn-lg mx-2" %>
  <% else %>
    <%= link_to "ログイン", new_user_session_path, class: "btn btn-success btn-lg mx-2" %>
    <%= link_to "サインアップ", new_user_registration_path, class: "btn btn-info btn-lg mx-2" %>
  <% end %>
</div>

3. 大会一覧ページ

すべての大会を一覧表示します。

app/views/tournaments/index.html.erb

<h1>大会一覧</h1>
<div class="row">
  <% @tournaments.each do |tournament| %>
    <div class="col-md-4 mb-4">
      <div class="card">
        <div class="card-body">
          <h5 class="card-title"><%= tournament.name %></h5>
          <p>開催日: <%= tournament.date.strftime("%Y-%m-%d") %></p>
          <p>最大参加人数: <%= tournament.max_participants %></p>
          <%= link_to "詳細を見る", tournament_path(tournament), class: "btn btn-primary" %>
        </div>
      </div>
    </div>
  <% end %>
</div>

4. 大会詳細ページ

大会情報とランキング、参加者一覧を表示します。

app/views/tournaments/show.html.erb

<h1><%= @tournament.name %></h1>
<p>開催日: <%= @tournament.date.strftime("%Y-%m-%d") %></p>
<p>参加可能人数: <%= @tournament.max_participants %></p>
<p>状況: <%= @tournament.status %></p>

<h2>参加者ランキング</h2>
<table class="table table-striped">
  <thead>
    <tr>
      <th>順位</th>
      <th>名前</th>
      <th>スコア</th>
    </tr>
  </thead>
  <tbody>
    <% @tournament.participants.order(score: :desc).each_with_index do |participant, index| %>
      <tr>
        <td><%= index + 1 %></td>
        <td><%= participant.user.name %></td>
        <td><%= participant.score %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<% if current_user&.admin? %>
  <%= link_to "ラウンドを開始", start_round_tournament_path(@tournament), method: :post, class: "btn btn-success mt-3" %>
<% end %>

5. 新しい大会作成ページ(管理者専用)

管理者が新しい大会を作成できます。

app/views/tournaments/new.html.erb

<h1>新しい大会を作成</h1>
<%= form_with model: @tournament, local: true do |f| %>
  <div class="mb-3">
    <%= f.label :name, "大会名" %>
    <%= f.text_field :name, class: "form-control" %>
  </div>
  <div class="mb-3">
    <%= f.label :date, "開催日" %>
    <%= f.date_field :date, class: "form-control" %>
  </div>
  <div class="mb-3">
    <%= f.label :max_participants, "最大参加人数" %>
    <%= f.number_field :max_participants, class: "form-control" %>
  </div>
  <%= f.submit "大会を作成", class: "btn btn-primary" %>
<% end %>

6. 対戦結果入力ページ

管理者または出題者が対戦結果を記録します。

app/views/matches/edit.html.erb

<h1>対戦結果を記録</h1>
<%= form_with model: @match, local: true do |f| %>
  <div class="mb-3">
    <%= f.label :result, "勝者を選択" %>
    <%= f.select :result, options_for_select([["Player 1", "player1"], ["Player 2", "player2"], ["引き分け", "draw"]]), class: "form-select" %>
  </div>
  <%= f.submit "結果を保存", class: "btn btn-primary" %>
<% end %>

7. プロフィール編集ページ

ユーザーがプロフィール情報を編集します。

app/views/devise/registrations/edit.html.erb

<h1>プロフィールを編集</h1>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
  <div class="mb-3">
    <%= f.label :name, "名前" %>
    <%= f.text_field :name, class: "form-control" %>
  </div>
  <div class="mb-3">
    <%= f.label :email, "メールアドレス" %>
    <%= f.email_field :email, class: "form-control" %>
  </div>
  <%= f.submit "更新する", class: "btn btn-primary" %>
<% end %>

これで、**「MatchPath」**に必要なすべてのビューが完成しました。
次に進むべきエリアがあれば教えてください!