fv17の日記 - Coding Every Day

Webエンジニアの備忘用ブログです。主にWeb界隈の技術に関して書いています。

Railsの設計関連の記事まとめ

Railsの設計を学ぶ。
Railsに詳しい方々にコレ読みなさいと教えていただいたリンク集、と自分の学んだことメモ。

Ruby on Railsの正体と向き合い方

ポイント

  • Railsは小〜中規模開発に向いているが、どこかで限界が来る
  • 限界に対して、コード、アーキテクチャレベルで対処したい
  • 正体編では、「いつ、なぜ限界を迎えるのか?」を明らかにする
  • 向き合い方編では、既存の対処方法を俯瞰的な視点から捉えて提示する

Railsの正体

・DHHの設計思想:少人数のスタートアップでのプロダクト開発で「早くて綺麗」を実現
・それゆえのRailsのアプローチ:ModelのCRUD操作を中心にコードを整理して考える、書く量を減らす

限界について

・いつ: あるmodelが複数の異なるユースケースCRUD操作されるようになった時
・なぜ: あるmodelに書かれたValidations/Callbacksは特定のユースケースと密結合しているため

限界の表出の仕方

・特定の条件でValidations/Callbacksを実行 or スキップする
・Controller内に 'ApplicationRecord.transaction'を書く

限界との向き合い方

1.コードレベル:正面から解決するアプローチ

 ユースケース固有の処理を書く層を作り、共通処理のみModelに書く
 例:ActiveRecordの分割、Application Modelの導入、Form/Service(そのほか諸々のPORO)の導入

2.アーキテクチャレベル:そもそも回避しようとするアプローチ

 ・対象とするドメインを小さくする
 ・複数のサブシステムに分割する

レールの伸ばし方

ポイント

  • 人間が見て、一目で分かるようなコーディングにすべし!
  • 適切な抽象化をしよう

問題1: 1メソッドでごちゃごちゃ書いていて何しているか分からない

問題
  • 一目見て何をしているのか分からない
解決策
  • メソッドに切り分けて、一目で何をしているか分かるようにする

問題2: Fat Controller問題(Controllerの1アクションがカオス)

問題
  • 一目見て何をしているのか分からない
解決策
  • 基本的にロジックは全てモデルに任せる
  • Controllerの責務は以下の3つであると意識する

 ・モデルのメソッドを呼ぶ
 ・インスタンス変数への代入
 ・ビューの選択、もしくはリダイレクト先の選択

問題3: Fat Model問題

問題
  1. Model間の密結合により、複数モデルにまたがる処理が増える、修正の影響範囲が広くなる
  2. 複数レコードを扱う処理をクラスメソッドで書いてしまう
  3. 上記の結果、特定モデルに処理が集中し、行数が多くなり理解しづらい
解決策
  • POROに切り出す ex. PostWithNotificationsクラス

問題4: 大量のbefore_filter

問題
  • 一つのアクションで何が実行されているか分からない
  • 最終的にどんなインスタンス変数が設定されているか分からない
解決策
  • before_filterは使わず、各アクションからメソッドを呼ぶ
  • 呼び出したメソッド内部でインスタンス変数を設定せず、呼び出し側で設定する
  • インスタンス変数やプライベートメソッドが大量の場合は、ビューに渡す変数を抽象化

問題5: validationやcallbackの場合分け

問題
解決策
  • Form Objectで分割する

問題6: 一つのアクションでやることが大量

問題
  • 一目見て何をしているのか分からない
解決策
  • Serviceを導入し、アクションの詳細部分を担ってもらう