モデルを整理しようこの広告は、90日以上更新していないブログに表示しています。様々な機能を使って、共通化や抽象化、シンプルなコードへの書き換えなどを行えるようになっています。今回はモデルに焦点を絞り、それらをまとめていきたいと思います。整理を始める前に気をつけるべきことをまとめておこうと思います。同じであることが多いのではないかと思います。自分向けの情報整理です。Object整理する前にApplicationRecord整理する前にDecorator整理する前にInteractor整理する前にSTI(単一テーブル継承)まとめコールバックコールバックは以下のような、特定のメソッド呼び出し時の前後などに自動的に呼び出される処理を宣言的に記述する方法です。}end整理する前にコールバックはシンプルな機能に絞るコールバックを複雑化することで、実行フローのどこで変更がかかったかわからなくなる可能性があります。自動的にデータに変更がかかることは便利ではありますが、特にチーム開発では大きな問題となります。}endこのようなコールバックがあった場合、ミドルネームを考慮して対応する事になった場合でも、モデル側のコールバックに気が付かないと途中にミドルネームを対応する処理を加えても勝手にミドルネームなしの名前になってしまいます。確実に変更として加えて良いようなものなどに絞っておくのが良いでしょう。同じように走ることになります。テスト時に走ってしまうと困るような重い処理や、外部APIアクセスなどは避けるべきでしょう。コールバックをクラスに分離するコールバックはブロック、シンボル、オブジェクトで記述できます。例としてはブロックによる記述をしましたが、名前付けをする意味でもシンボルかオブジェクトによる記述を心がけるべきでしょう。シンボルではなく、クラスに分離してコールバックを実装する理由は何でしょうか。特定の機能に対して複数のコールバックが設定される場合に、1つのクラスにまとめて記載することができる(責務の分離)テストをコールバックのみに集中して記述できる一方で分離しすぎると不必要にコード量が増えて追いにくくなるため、単にコールバックを追い出すのではなく、特定の責務というまとまりを意識して分離すべきでしょう。...endちなみにコールバックは適切に記述しておく必要があり、それぞれの順序や特性を理解しておく必要があります。ガイドバリデーションバリデーションもコールバックと同じようにシンボルやクラスに分離することができます。trueEachValidator、PresenceValidator、UniquenessValidatorEachValidatorやPresenceValidator、UniquenessValidatorなどを用いると、単一の属性に対するバリデーションを行うことができます。ような名前のクラスを実装したい各Validatorクラスを継承して実装することで対応できます。利用を検討すると良いかと思います。メソッドを利用するのが良いでしょう。クラスを指定すると、影響範囲を抑えながらバリデーションの処理を整理することができます。ガイドを見るのが早いと思います。ガイド値オブジェクトドメイン駆動設計を知っている人であれば、値オブジェクトの利用を検討することがあるでしょう。値オブジェクトとは、一意識別を必要としない状態管理をしないオブジェクト(不変なオブジェクト)のことを指します。値オブジェクトとcomposed_of値オブジェクトを切り出してみます。最初にUserクラスに郵便番号と住所があるとして、それをAddressという値オブジェクトに切り出してみます。endend値オブジェクトの利点として、ビジネス的なまとまりをクラス化できるとともに、それに関連するビジネスロジックを適切に分離できる点にもあります。継承することも検討するとよいです。Addressオブジェクトを利用して生成したりできるようになります。ない場合は複雑化するため、その場合は使用せずに書いてしまったほうがわかりやすいかもしれません。利用することで簡単に書くことができるようになります。ように振る舞う)のような関係といえるものです。Mix-inを使うべきではないでしょう。モジュール化する単位をクラスの切り出しと同様にきちんと考える必要があります。いう名前を考えてみると良いかもしれません(単なる思考停止というより思考の基準として利用すると良いと思います)。これは分離というよりも意味のある単位で名前付けできることが利点となります。endend共通化や分離が適切でないものの、振る舞いのまとまりに名前をつけて整理したい場合に有効です。ような機能を利用しつつ実装できるようになります。このあたりの機能は前に記事にまとめているのでこちらを参考にしてください。フォームによるActiveRecordを通した登録や更新などは、単一のActiveRecordクラスに対応するときは難しくはありませんが、複数に対応している場合などはモデルにあるべきロジックが他のレイヤーに出てしまうなどの懸念があります。いう形で集約し、複数にまたがるバリデーションなどを記載できます。一方で、単に長大なフォームのデータを押し込めるオブジェクトとするべきではありません。これはオブジェクト指向としての一般的な問題です。これらの複雑性に対して(多数の異なるドメインへの入力をフォームが受け付ける場合や複雑な永続性など)はその処理を行うオブジェクトなどに分離し、適切な責務の分離をするべきでしょう。渡した場合でも適切なControllerへのパスが生成されるようになります。シリーズを利用すると良い場合もあると思います。これらについては以下のページが参考になります。継承したクラスを作った上で、モデルの継承元を自前で書き換えるなどしなくても、モデル全体を通して追加したい機能を追加することができます。外部のプラグイン等には影響しない形で追加できるのも利点です。利用するタイミングは限られていますが、都度モデルに機能を追加していたりする場合にアプリケーション全体で追加して良いと判断したら、こちらを利用することを検討すると良いでしょう。狭義として、「モデルからビューに出すときに加工するといったロジックを乗せるオブジェクト」として使われていることが多いです。これはヘルパーメソッド、モデル、ビューのどこに書いても都合があまり良くないこの種のロジックを記述する場所を提供してくれます。適切な粒度に分離していくことが大切です。利用して実装することが多く、ちょっとした設定や呼び出しによって簡単にActiveRecordのモデルを呼び出すように利用できるので、それらを紹介している記事へのリンクを記載しておきます。制約が殆どないため、個々の開発者がどのようなルールで命名し、どのような粒度で導入し、どのような意図でオブジェクトを実装したかを全員が理解できるように務める必要があります。これはチーム開発では難しいかもしれません。よって導入することができます。READMEを参考にするのが良いかと思います。対応したい機能を実装できます。このルールを、開発する全員が理解する必要が出てくるため、導入するメリットがあるような複雑なビジネスロジックが出てきたときに導入するのが良いでしょう。異なるモデルクラス間で共通化ができる非常に強力な機能です。カラムに保存されます。これは共通化する上で非常に便利に感じますが、一方で欠点も多くあります。カラムの値を変更する必要がある1テーブルに複数のデータが詰め込まれるため、パフォーマンスの問題がある一度導入すると他の継承関係を利用できなくなる各クラスでの変更に対して、逐一保存済みのデータを修正していく必要があり、保守にかかるコストが高いまた、単純にテーブルとして見た場合に理解するのも難しい部分があるので、その点も注意が必要です。これらを踏まえた上で、以下のようなパターンに当てはまるときに導入を検討するとよいかと思います。ビジネスドメインの知識として、共通化されるべきである検索等の理由から、共通のテーブルにデータが含まれていることが望ましいほとんどのカラムが共通であり、今後もその共通性がほとんど変化しないと想定される個人的にも利用経験がありますが、追加は良いのですが属性の削除や更新には弱いので、単なる設計上の決定ではなく、他のもの以上にビジネス的な知識をしっかりと確認した上での導入が良いかと思います。機能によるものをメインとしていました。してみた場合、他にも様々な方法が考えられると思います。例としては、以下のサイトにまとまっているようなオブジェクトを導入する方法です。techracho.bpsinc.jpまた、CQRS(コマンドクエリ責務分離)などにより、複雑性を排除することも検討できるかと思います。なんにせよ、適切な粒度で責務を分離し、適切な命名をしたオブジェクトやモジュールを導入することが求められるでしょう。読者になるはてなブログをはじめよう!naokirinさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。