Active Recordのバリデーションやコールバックについて深く掘り下げてみた
Active Recordの関連付け(アソシエーション)
この項目については、データベースのリレーションについて知っていると、理解の助けになると思います。「社員は部署に、部署は会社に属する」などのように、「社員」「部署」「会社」といったモデル間の関連付けをする機能です。様々な関連付けの種類があるので、図にまとめてみました(図の中のコードは分かりやすいように簡略化しているので、実際は文法に即して記述します)。
基本的なbelongs_toとhas_many
複数の注文を1人の顧客が行っているような場合には、「注文」モデルと「顧客」モデルの両方面から「belongs_to(~に属する)」と「has_many(~を複数持つ)」をそれぞれ指定します。ここでのポイントは、belongs_toを使う際は、関連付けるためのID(下記の例では「顧客ID」)の属性を「注文」モデルに追加するマイグレーションが必要ということです。
「注文 belongs_to 顧客」に「counter_cache: true」を追加しておくと、ある顧客の合計注文数が増減したときにその顧客の「注文数」属性が自動で更新されるようになります。そうすると、顧客の総注文数を知りたいときに、わざわざ注文モデルのデータを取得しなくても済みます。couter_cacheを使った方がいいかどうかは、検索と更新どちらの頻度が高いかで決まります。図2の例では、顧客モデルの「注文数」属性はマイグレーションで追加することになります。
「注文 belongs_to 顧客」に「dependent: :destroy(または:delete)」を追加しておくと、ある顧客のデータがdestroyされたときに、関連する注文も削除されるようになります。
「注文 belongs_to 顧客」に「touch: true」を追加しておくと、ある顧客のデータが保存、またはdestroyされたときに、関連する注文のタイムスタンプが更新されるようになります。
別のモデルを仲介(through)するbelongs_toとhas_many
医者と患者の関係は、予約を介して結び付けられます。このようなときに「through」を使います。
ある医者が担当する患者を知るためには予約を仲介し、ある患者を担当する医者を知るためにも予約を仲介します(診察ごとに担当医が違うこともありますよね)。
「予約」モデルのように、「医者」と「患者」の関連付け以外の属性(予約日時など)がある場合に「through」を使います。
関連先のデータを1つしか持たないhas_one
販売者がそれぞれアカウントを1つだけ作成できる場合などには、「has_one」で関連付けます。関係が1:1ならば1つのモデルにまとめても構わないと思いますが、この方が使いやすいのかもしれませんし、将来的に「has_many」に変更しやすいのかもしれません。
「has_one」でも「has_many」と同じように「belongs_to」や「through」を設定できます。
関連付けるだけのhas_and_belongs_to_many
単に2つのモデルを関連付けるだけの場合は、「through」せずに「has_and_belongs_to_many」で関連付けます。「医者_病院」モデルには自身のIDは不要です。has_many_and_belongs_to_manyを使うときは、関連付けテーブルを作成するためのマイグレーションが必要です。
複数の関連付けを行うポリモーフィック
DRY(Don't Repeat Yourself:同じことを繰り返さない)の原則に基づいて、重複しているモデルを1つにまとめてしまう機能です。
図7の例では、医者も患者も自分の顔写真を登録できますが、「医者の顔写真」「患者の顔写真」の2つのモデルは構成がほぼ同じです。
これらを1つの「顔写真」というモデルにまとめ、ある顔写真が医者と患者どちらのモデルに属するかを、「対象のタイプ」(この例の場合、imageable_id)で指定します。「対象のID」(この例の場合、imageable_id)は医者IDか患者IDです。
自己結合のsubordinate
組織の階層のように、同じモデルのデータに関連付けるときに使うのが「subordinate」です。
最後に
いかがでしたか? バリデーション、コールバック、関連付けには他にも様々な機能があります。ガイドにはさらに詳しく書いてありますので、この記事を読んだ後にまたトライしてみてください。「こういう機能はすでにあったよなー」という程度の記憶でも、覚えておけば開発に役立つと思います。それではまた!
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- Active Recordの使い方
- Railsでデータベースを扱うためのライブラリActive Recordについて学んでみた
- Oracle Cloud Hangout Cafe Season7 #2「IaC のベストプラクティス」(2023年7月5日開催)
- Installing OpenSolaris
- 多機能なHibernate(後編)
- Active Recordのその先へ ~RailsでMongoDBを使う~
- Iacツール「Terraform」の基本的な使い方
- Let's discover OpenSolaris!
- HTTPセッションの永続性確保
- ZFS and DTrace make management easy