1対多の関係について(改めて理解しよう)
この記事では、Railsでテーブルを1つでも作成したことがある人を前提とします。
なので実際にテーブルを作成するマイグレーション関連のことは割愛します。
さて、テーブルの関係性についてですが、今回は”User”と”Book”の2つのモデル(テーブル)を用いて解説していきます。
2つのテーブルをER図で
テーブルの関係性を表すER図(EntityRelationship)を見てみましょう。
“User”が1で、”Book”が多の関係となっており、これは1人のユーザーが複数のBook(本)を登録できることになります。
実際のアプリケーションの画面では、ユーザーがフォーム画面からBookを新規投稿していくイメージですね。
イメージ的には、Twitterで1人のユーザーが何回もツイートできる関係性と同じです。
Railsコードの解説
ここからは、モデルやコントローラーの記載について解説していきます。
モデルのリレーションを組む
まずは、予め作成した”User”と”Book”のそれぞれにリレーションの記述を追加します。
Userモデルから見た時に、Bookモデルは複数存在する”多”の関係なので、has_many を記述します。
dependent: :destory の記述は、「ユーザーが消されると、そのユーザーに紐づくBookも削除する」という意味なので、これはあっても無くてもどちらでも大丈夫です。
Bookモデルから見た時に、Userモデルは1つしか存在しない”1”の関係のため、belongs_to を記述します。
このモデルはこれだけで、他は特に記述不要です。
フォーム画面を作成
画面側のコードはいたって普通な感じなので、コードの紹介までにしておきます。
コントローラーでのレコード登録
2つのテーブルを関連付けた場合、どちらかのテーブルには他方のテーブルのidが登録必須になっている場合がほとんどです。
今回の場合は、Bookを新たに登録する際にUserのid (user_id) が指定必須となります。
このため、単純にコントローラーのcreateメソッド処理を書くとこのようになります。
※この例ではUserにはdeviseでログイン機能をつけているため、“current_user”が使用可能となってます。
deviseなど使っていなければ、User.find(id) などでユーザーのオブジェクトを取得するようにしてください。
このコードのミソは、@book.user_id に直接current_user.idを入れていることです。
これで「どのユーザーがBookを登録しようとしているか」を指定できます。
しかし、このコードをもっとスッキリさせることができます。
せっかくリレーションを組んでいるので、最大限活かしましょう。
次のようなコードになります。
さきほどの user_id を指定してた箇所が無くなりました。
代わりに2行目が current_user から始まるようになっています。
これは、「current_user に紐づくレコードだよ」とあらかじめ宣言する方法です。
これによりBookのレコードの user_id カラムには current_user のidが自動的に入るようになるんです!
ちなみに今回は1対多の関係でしたが、1対1の関係性でも同じ方法で記述できます。
要は、親側のモデルを起点にするとリレーションが上手いこと自動的にやってくれる、という感じですね。
まとめ
- モデルでリレーションを組む
- has_many
- belongs_to
- (view画面を作っておく)
- コントローラーでレコード登録の記述をする
コメント