RailsでWebアプリ設計するときに考えていること
言葉で説明できない秘伝のタレになっているので出来る限り言葉で表現してみたい
定期的に見直してはいるのであくまで現時点のもの
- やりたいことを抽出する。後でメンタルモデルで表現できるように登場する事柄とか操作とかをざっくりメモっておく
- 画面を想像してみる(これが一番手っ取り早い。ただ、本当にやりたいことが見えている場合のみ)
- 操作を想像してみる
- 誰が何をどうしてどうなりたいか想像してみる
- シナリオやユーザストーリを考える。チームでやる場合は会話のネタにUMLやBPMNを補助的に駆使してもいいかも
- 関心事を整理する
- 関心事からざっくりモデルを作成する
- ただ私はDDD信者ではないというか、エンティティと値オブジェクトに分けるとかリポジトリ用意するのが好みではないのとRailsのCoCに合わないと思っている
- オブジェクト指向で気持ちよく振る舞える感じを目指している(このへん上手く言語化できないなぁ)
- この辺からテストを書いている(BDD)
- 基本的には ActiveRecord パターンに従っていればいいと思います
- モデル間の関連を定義する
- モデルの入出力を考える
- DBテーブルの1行に関係する処理か、DBテーブル全体に関係する処理か、DBのテーブルを複数複数必要とする処理か考える
- DBテーブルの1行に関係する処理の場合は別に用意しなくてもよいし、必要であれば def method_name でインスタンスメソッドを定義する
- DBテーブル全体に関係する処理の場合、参照系の場合は scope を用意する。scope で済まない処理の場合は def self.method_name でクラスメソッドを定義する
- DBのテーブルを複数複数必要とする処理の場合にどこに書くかが一番むずかしい。主に以下のアプローチを採用していると思う。
- バリデーションを定義する
- テストは shoulda-matchers が便利
- 特殊なバリデーションとか処理が必要な場合、モデルにロジックを書かずに gem を使う or 用意するか、lib/validators みたいなディレクトリを作って管理する
- もっと上位のメンタルモデルが生まれて抽出できる場合があればそれはそれでいい
- あるモデルでIPアドレスを扱う処理が増えてきて lib/validators の責務を超えた場合は lib/models あたりに module 作って移すとか
- 基本的に ActiveRecord に関係ない処理(ただし、ビューの表示部分以外)は concerns(あんまり使わない) か lib/models に書いている
- DBテーブルの1行に関係する処理か、DBテーブル全体に関係する処理か、DBのテーブルを複数複数必要とする処理か考える
- JSONシリアライズは app/serializers を使っている(ActiveSerializer)
- テストは json_spec が便利
- 画面表示用の特殊処理はhelperに書く
- ただ、デフォルトだと foo_helpers に書いても foo 画面以外で使えてしまうので config.action_controller.include_all_helpers は false にしている
- モデルとビューの橋渡し役をhelperで行うことにしている
- コントローラではリクエストの値をモデルに渡して処理させてビューを表示するだけにする
- ルーティングは基本的にRESTでCRUDを取捨選択する感じで行う(基本的には resources :foo で済むようにする)
書いてはみたものの、この感覚と流れをチームで共有するためには相当な修練が必要な気がしてきたなぁ・・・