レールルで Controller から ActiveRecord を生で触るのをやめたい話

単純な操作ならいいんだけど、複数テーブルに対してごにょっと操作をして、それがアトミックでなくてはならなくて、みたいなときの話。

単純な複数テーブルに対する操作なら多分主従の関係みたいなのあると思うしそういうときには主のほうを表すARを継承したモデルクラスにメソッド生やせばいいかなって思う(commentable なやつに comment 書くとかそういうの)んだけど、これがもっと複雑な要件になってきて、しかもトランザクション制御が必要となったとき、テーブルそのもの(あるいはインスタンスならばその中の一行)を表すARクラスにトランザクションあるのめっっっっっっちゃ気持悪い。

なので、小規模なやつではトランザクションとかをコントローラーに書いてるんだけど、複雑になってきたときに破綻するのが目に見えてる。し、トランザクション制御ってビジネスロジックだよね〜〜〜。ほんらいそれはコントローラーにあるべき処理ではない。

なので、たとえば「とあるユーザー A がリソース A を変更する権限を持っているかチェックして、権限を持っていたらリソース A を変更する、そんで、そのリソース A へのアクセス権をもっている他のユーザ B ,ユーザ C への通知を書き込む」みたいなやつは、少しめんどうでもサービスクラスみたいなやつを作って、そこでトランザクション制御や複雑な処理を行うべきなのではないかという気持になっている。

が、アプリケーションが充分にシンプルな間はそういうことしなくていい気もするし、どのタイミングでそういうの導入するべきなのかむずかしい。

ただまあ、AR を継承したモデルが責務を持つのはあくまでリレーションを含めた「テーブル内のデータに変なデータが入り込まないようにする」「そのテーブルに対する操作に名前を付けて抽象化する」という部分であって、「ビジネスロジック的に不整合がないようにする」みたいなところに責務を持つクラスは別にきちんと作るべきなのかな、というのが最近のわたしの考え方です。