124 lines
13 KiB
Markdown
124 lines
13 KiB
Markdown
---
|
||
description: 'Ruby on Railsのコーディング規約とガイドライン'
|
||
applyTo: '**/*.rb'
|
||
---
|
||
|
||
# Ruby on Rails
|
||
|
||
## 一般的なガイドライン
|
||
|
||
- RuboCopスタイルガイドに従い、一貫性のあるフォーマットのために`rubocop`、`standardrb`、`rufo`などのツールを使用する。
|
||
- 変数/メソッドにはsnake_case、クラス/モジュールにはCamelCaseを使用する。
|
||
- メソッドは短く、焦点を絞る;複雑さを減らすために早期リターン、ガード節、プライベートメソッドを使用する。
|
||
- 短い名前や汎用的な名前よりも意味のある名前を優先する。
|
||
- 必要な時のみコメントを書く — 明らかなことの説明は避ける。
|
||
- クラス、メソッド、モジュールに単一責任原則を適用する。
|
||
- 継承よりもコンポジションを優先;再利用可能なロジックをモジュールやサービスに抽出する。
|
||
- コントローラーは薄く保つ — ビジネスロジックをモデル、サービス、またはコマンド/クエリオブジェクトに移動する。
|
||
- 「Fat Model, Skinny Controller」パターンを思慮深く、明確な抽象化で適用する。
|
||
- 再利用性とテスト性のためにビジネスロジックをサービスオブジェクトに抽出する。
|
||
- ビューの重複を減らし簡素化するためにパーシャルまたはビューコンポーネントを使用する。
|
||
- 否定条件には`unless`を使用するが、明確性のために`else`との組み合わせは避ける。
|
||
- 深くネストした条件分岐を避ける — ガード節とメソッド抽出を優先する。
|
||
- 複数の`nil`チェックの代わりに安全ナビゲーション(`&.`)を使用する。
|
||
- 手動のnil/空チェックよりも`.present?`、`.blank?`、`.any?`を優先する。
|
||
- ルーティングとコントローラーアクションでRESTful規約に従う。
|
||
- リソースを一貫してスキャフォールドするためにRailsジェネレーターを使用する。
|
||
- 属性を安全にホワイトリスト化するためにストロングパラメーターを使用する。
|
||
- より良いモデルの明確性と検証のためにenumと型付き属性を優先する。
|
||
- マイグレーションはデータベース非依存にする;可能な場合は生SQLを避ける。
|
||
- 外部キーと頻繁にクエリされるカラムには常にインデックスを追加する。
|
||
- モデルだけでなくDBレベルで`null: false`と`unique: true`を定義する。
|
||
- メモリ使用量を減らすため大きなデータセットの反復処理には`find_each`を使用する。
|
||
- 明確性と再利用性のためにモデルでクエリをスコープ化するかクエリオブジェクトを使用する。
|
||
- `before_action`コールバックは控えめに使用 — その中でビジネスロジックを避ける。
|
||
- 高価な計算や頻繁にアクセスされるデータの保存には`Rails.cache`を使用する。
|
||
- ハードコーディングの代わりに`Rails.root.join(...)`でファイルパスを構築する。
|
||
- 明示的な関係性のためにアソシエーションで`class_name`と`foreign_key`を使用する。
|
||
- `Rails.application.credentials`または環境変数を使用してシークレットと設定をコードベースから除外する。
|
||
- モデル、サービス、ヘルパーの分離されたユニットテストを書く。
|
||
- エンドツーエンドロジックをリクエスト/システムテストでカバーする。
|
||
- メール送信やAPI呼び出しなどのノンブロッキング操作にはバックグラウンドジョブ(ActiveJob)を使用する。
|
||
- テストデータをきれいにセットアップするために`FactoryBot`(RSpec)またはfixtures(Minitest)を使用する。
|
||
- `puts`の使用を避ける — `byebug`、`pry`、またはロガーユーティリティでデバッグする。
|
||
- 複雑なコードパスとメソッドをYARDまたはRDocで文書化する。
|
||
|
||
## アプリディレクトリ構造
|
||
|
||
- ビジネスロジックをカプセル化するため`app/services`ディレクトリにサービスオブジェクトを定義する。
|
||
- 検証と送信ロジックを管理するため`app/forms`に配置されたフォームオブジェクトを使用する。
|
||
- APIレスポンスをフォーマットするため`app/serializers`ディレクトリにJSONシリアライザーを実装する。
|
||
- リソースへのユーザーアクセスを制御するため`app/policies`に認可ポリシーを定義する。
|
||
- `app/graphql`内でスキーマ、クエリ、ミューテーションを組織化してGraphQL APIを構造化する。
|
||
- 特殊な検証ロジックを強制するため`app/validators`にカスタムバリデーターを作成する。
|
||
- より良い再利用性とテスト性のため`app/queries`で複雑なActiveRecordクエリを分離・カプセル化する。
|
||
- ActiveModelタイプ動作を拡張またはオーバーライドするため`app/types`ディレクトリにカスタムデータ型と変換ロジックを定義する。
|
||
|
||
## コマンド
|
||
|
||
- 新しいモデル、コントローラー、マイグレーションを作成するため`rails generate`を使用する。
|
||
- データベースマイグレーションを適用するため`rails db:migrate`を使用する。
|
||
- 初期データでデータベースを投入するため`rails db:seed`を使用する。
|
||
- 最後のマイグレーションを元に戻すため`rails db:rollback`を使用する。
|
||
- REPL環境でRailsアプリケーションと対話するため`rails console`を使用する。
|
||
- 開発サーバーを開始するため`rails server`を使用する。
|
||
- テストスイートを実行するため`rails test`を使用する。
|
||
- アプリケーション内の定義されたすべてのルートをリストするため`rails routes`を使用する。
|
||
- 本番用にアセットをコンパイルするため`rails assets:precompile`を使用する。
|
||
|
||
## API開発ベストプラクティス
|
||
|
||
- RESTful規約に従うためRailsの`resources`を使用してルートを構造化する。
|
||
- バージョン管理と前方互換性のため名前空間化されたルート(例:`/api/v1/`)を使用する。
|
||
- 一貫した出力のため`ActiveModel::Serializer`または`fast_jsonapi`を使用してレスポンスをシリアライズする。
|
||
- 各レスポンスに適切なHTTPステータスコードを返す(例:200 OK、201 Created、422 Unprocessable Entity)。
|
||
- リソースの読み込みと認可のため`before_action`フィルターを使用し、ビジネスロジックには使用しない。
|
||
- 大きなデータセットを返すエンドポイントにはページネーション(例:`kaminari`または`pagy`)を活用する。
|
||
- ミドルウェアまたは`rack-attack`などのgemを使用して機密エンドポイントをレート制限・スロットリングする。
|
||
- エラーコード、メッセージ、詳細を含む構造化されたJSON形式でエラーを返す。
|
||
- ストロングパラメーターを使用して入力パラメーターをサニタイズ・ホワイトリスト化する。
|
||
- 内部ロジックをレスポンスフォーマットから分離するためカスタムシリアライザーまたはプレゼンターを使用する。
|
||
- 関連データの先行読み込み時に`includes`を使用してN+1クエリを避ける。
|
||
- メール送信や外部APIとの同期などのノンブロッキングタスクにはバックグラウンドジョブを実装する。
|
||
- デバッグ、可観測性、監査のためリクエスト/レスポンスメタデータをログに記録する。
|
||
- OpenAPI(Swagger)、`rswag`、または`apipie-rails`を使用してエンドポイントを文書化する。
|
||
- 必要に応じてAPIへのクロスオリジンアクセスを許可するためCORSヘッダー(`rack-cors`)を使用する。
|
||
- 機密データがAPIレスポンスやエラーメッセージに決して露出しないことを確認する。
|
||
|
||
## フロントエンド開発ベストプラクティス
|
||
|
||
- WebpackerまたはesbuildでRails 6+のJavaScriptパック、モジュール、フロントエンドロジックを管理するメインディレクトリとして`app/javascript`を使用する。
|
||
- モジュラー性を保つためファイルタイプではなくコンポーネントまたはドメインでJavaScriptを構造化する。
|
||
- Rails-nativeアプリでリアルタイム更新と最小限のJavaScriptのためHotwire(Turbo + Stimulus)を活用する。
|
||
- HTMLに動作をバインドし、UIロジックを宣言的に管理するためStimulusコントローラーを使用する。
|
||
- `app/assets/stylesheets`下でSCSSモジュール、Tailwind、またはBEM規約を使用してスタイルを組織化する。
|
||
- 繰り返しマークアップをパーシャルまたはコンポーネントに抽出してビューロジックをクリーンに保つ。
|
||
- セマンティックHTMLタグを使用し、すべてのビューでアクセシビリティ(a11y)ベストプラクティスに従う。
|
||
- インラインJavaScriptとスタイルを避ける;代わりに明確性と再利用性のため別の`.js`または`.scss`ファイルにロジックを移動する。
|
||
- キャッシュと圧縮のためアセットパイプラインまたはバンドラーを使用してアセット(画像、フォント、アイコン)を最適化する。
|
||
- Rails生成HTMLとStimulusでフロントエンドインタラクティビティをブリッジするため`data-*`属性を使用する。
|
||
- システムテスト(Capybara)またはCypressやPlaywrightなどのツールを使用した統合テストでフロントエンド機能をテストする。
|
||
- 本番環境で不要なスクリプトやスタイルを防ぐため環境固有のアセット読み込みを使用する。
|
||
- UIを一貫性があり拡張可能に保つためデザインシステムまたはコンポーネントライブラリに従う。
|
||
- 遅延読み込み、Turboフレーム、JS遅延を使用してfirst-paint時間(TTFP)とアセット読み込みを最適化する。
|
||
|
||
## テストガイドライン
|
||
|
||
- ビジネスロジックを検証するため`test/models`(Minitest)または`spec/models`(RSpec)を使用してモデルのユニットテストを書く。
|
||
- テストデータをきれいで一貫して管理するためfixtures(Minitest)または`FactoryBot`でのfactories(RSpec)を使用する。
|
||
- RESTful API動作をテストするため`test/controllers`または`spec/requests`下でコントローラーspecを組織化する。
|
||
- 共通テストデータを初期化するためRSpecの`before`ブロックまたはMinitestの`setup`を優先する。
|
||
- テストでの外部API呼び出しを避ける — テスト環境を分離するため`WebMock`、`VCR`、または`stub_request`を使用する。
|
||
- 完全なユーザーフローをシミュレートするためMinitestの`system tests`またはRSpecのCapybaraでの`feature specs`を使用する。
|
||
- 遅くて高価なテスト(例:外部サービス、ファイルアップロード)を別のテストタイプまたはタグに分離する。
|
||
- 適切なコードカバレッジを確保するため`SimpleCov`などのテストカバレッジツールを実行する。
|
||
- テストで`sleep`を避ける;MinitestやRSpecでActiveJob::TestHelperを使用して`perform_enqueued_jobs`を使用する。
|
||
- テスト間でクリーンな状態を維持するためデータベースクリーニングツール(`rails test:prepare`、`DatabaseCleaner`、または`transactional_fixtures`)を使用する。
|
||
- `ActiveJob::TestHelper`または`have_enqueued_job`マッチャーを使用してジョブをエンキューし実行してバックグラウンドジョブをテストする。
|
||
- CI ツール(例:GitHub Actions、CircleCI)を使用して環境間でテストが一貫して実行されることを確認する。
|
||
- 再利用可能で表現力豊かなテストロジックのためカスタムマッチャー(RSpec)またはカスタムアサーション(Minitest)を使用する。
|
||
- より高速で対象を絞ったテスト実行のためタイプ(例:`:model`、`:request`、`:feature`)でテストをタグ付けする。
|
||
- 脆弱なテストを避ける — 明示的に必要でない限り特定のタイムスタンプ、ランダム化されたデータ、または順序に依存しない。
|
||
- 複数レイヤー(モデル、ビュー、コントローラー)にわたるエンドツーエンドフローの統合テストを書く。
|
||
- テストを高速、信頼性があり、本番コードと同じくらいDRYに保つ。
|