LoginSignup
17
17

More than 5 years have passed since last update.

はじめてのRailsアソシエーション【1対多】

Last updated at Posted at 2018-04-12

はじめに

Railsのアソシエーションについて調べたことをまとめます。
ここでは、SNSのようなサービスを例に「1対多」の関係を考えていきたいと思います。

アソシエーションとは

アソシエーション(association)=関連付け

Railsでのアソシエーションとはモデル同士のつながりのことを指します。
モデル同士を関連付けておくと、関連するモデル同士のデータの操作が簡単になるメリットがあります。

関連付けることのメリット

ここで例にあげたSNSのようなサービスでは「ユーザー」と「投稿」を関連付けておくと下記のようなメリットがあります。
これらは関連付けされた時に追加されるメソッドを利用して実現できます。

  • 「ユーザー」を削除した時にそのユーザーの「投稿」も全て削除できる
  • 新しく「投稿」を作成した時、自動で「ユーザー」との関連付けをおこなう
  • 「投稿」や「ユーザー」に関連付く内容を簡単に取り出せる
    • 「ユーザー」の持ってる「投稿」の数はいくつか(空か)
    • 「ユーザー」の持ってる「投稿」の検索 など

ユーザー と投稿の関係

SNSではユーザーが何らかの投稿をしますが、

  • ユーザーは複数の(0個以上の)投稿ができます。
  • 1つの投稿に対して投稿者として関連付くユーザーは1人だけです。

1人のユーザーに対して多数のツイートが関連付くこのような関係を、「1対多」の関係といいます。

モデル同士で1対多の関係を関連付ける

モデル同士の関連付けをするためには、お互いのモデルに関係性の記述が必要となります。

テーブルに外部キーを追加する

「多」側は「1」側に従属する関係となり、この従属する側のテーブルに「外部キー1」を追加する必要があります。
ここではpostsテーブルに"user_id"を追加します。
この"user_id"によって「ユーザー」と「投稿」が関連付けされます。

モデルファイルに関係性を記述する

1対多の関連付けをするためには下記2つを使います。

  • belogns_to
  • has_many

belogns_to

「多」側に"belongs_to"を追加します。

app/models/post.rb
class Post < ApplicationRecord
  belogns_to :user
end

postモデルに"belogns_to :user"と記述します。
モデル名と合わせて読むと、"post belongs to user"。直訳すると「ポスト(投稿)はユーザー属します」と読めます。
これで、投稿に対してユーザーが関連付きます。

has_many

「1」側には"has_many"を追加します。

app/models/user.rb
class User < ApplicationRecord
  has_many :posts, dependent: :destroy
end

userモデルに"has_many :posts"と記述します(ポストは複数あるので「posts」と複数形にします)。
こちらもモデル名と合わせて"user has many posts"とすれば、「ユーザーには多くのポスト(投稿)があります」読むことが出来ます。
また、「dependent: :destroy」を追加すると、前述したユーザーを削除したときにユーザーの投稿も全て削除することができます。

まとめ

関連付けすることによってデータの操作がわかりやすく、簡単になることが分かりました。
今回は1対多の関連付けについてまとめましたが、1対1、多対多の関連付けも存在します。
学習を進め気づいたことがあれば追記していきたいと思います。


参考:https://railsguides.jp/association_basics.html


  1. 他のテーブルとの関連付けに使うキーのこと。外部キーには関連付けされた先の「主キー2」が入ります。 

  2. データベース作 成時に自動で付く「id」のこと。 

17
17
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
17