Help us understand the problem. What is going on with this article?

【Rails】多対多の関連付け

1体多関連の復習

まずは1体多の関連を復習し、それからどのような場合に多対多の関連を付けるべきなのかを見ていきましょう。

関連ですので、二つモデルを用意します。一つはAuthorもう一つはBookにしましょう。

それぞれ著者と書籍を表すクラスです。書籍は一人の著者に書かれており、一人の著者は複数の書籍を出版しているとします。
aso1.png

この時、1体多の関連を作成するには、Bookクラスにauthor_idというカラムを定義し、次のようにクラスを記述するのでした。

class Author < ApplicationRecord
  has_many :books
end

class Book < ApplicationRecord
  belongs_to :author
end

このように定義することで、次のようなメソッドを使うことができます。

author = Author.find(id)
# ある著者が書いた書籍の配列
# author_idがauthorのidと同じ値であるbookを取得
author.books

book = Book.find(id)
# ある書籍の著者
# bookが持つauthor_idと同じ値をidに持つauthorを取得
book.author

しかし、実際には一つの書籍に複数の著者がいるという状況の方が一般的です。

ですので、book.authorsauthor.booksの双方向で複数の値を取得できるのが理想的です。現状、bookには一つのauthor_idを持つことしかできないので、何かしらの改修が必要になります。

多対多の実装

そこで多対多の関連が必要となってきます。
多対多の関連にはAuthor,Bookの他に中間クラスと言われるAuthorBookクラスを追加します。
このAuthorBookクラスはauthor_idとbook_idを持っており、著者と書籍の関連1つに付き1レコード生成されます。

ではモデルを作っていきましょう。

rails g model author_book author:references book:references
rake db:migrate

author:references,book:referencesと書くことでそれぞれのクラスと紐付けがされます。

次に各クラスを修正していきます。

class Author < ApplicationRecord
  has_many :author_books
  has_many :books, through: :author_books
end


class Book < ApplicationRecord
  has_many :author_books
  has_many :authors, through: :author_books
end

class AuthorBook < ApplicationRecord
  belongs_to :book
  belongs_to :author
end

aso2.png

これで準備は整いました。では実験してみましょう

book = Book.create
author1 = Author.create
author2 = Author.create
book.authors

この時点ではまだ中間クラスによる関連付けが存在しないので、書籍に関連する著者は表示されないはずです。

AuthorBook.create(author_id: author1.id, book_id: Book.id)
AuthorBook.create(author_id: author2.id, book_id: Book.id)
book.authors

では次はどうでしょうか?
設定がちゃんと出来れいれば2つのauthorインスタンスが表示されているはずです。

簡単ですが多対多の関連付けの説明は以上になります。

多対多の関連は例えば、投稿に対するイイね機能や俳優と出演作品の関連などに用いられます。
複数のモデルが出てきて複雑になってきましたが、使いこなして複雑なデータ構造も扱えるようにしましょう。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした