Posted at

railsアソシエーションオプションのメモ

More than 1 year has passed since last update.


アソシエーションで利用するオプションメモ

最近開発していて、利用するオプションが増えてきたので、一度まとめておこうかと思います。

メモ書きですのでご了承。。。。


class_name

一つのモデルに対して、二つのアソシエーション経路を組む場合に多用します。

二つアソシエーションを組む場合は、経路を指定する必要がありますが、モデルが一つのため、

別経路なのに取りに行くモデルが同じということが起こります。これを防ぐために、class_nameがあります。

これのおかげで便宜的にモデルを二つに分けることができ、実際は一つのモデルを見に行くということができます。

例えば。。。。

本を売り買いできるサービスがあったとして、自分が売った本一覧と買った本一覧を見ることができるとします。

単なるアソシエーション(user.booksとか)だと、userがそのbookに対してどのようなアクションを行ったのかが判別できません。

なのでclass_nameを利用して、経路を二つ用意してやります。

user1に対してbook多になります。


user.rb

has_many :bought_book, class_name: "Book"

has_many :sold_book, class_name: "Book"


book.rb

belongs_to : "User"


こうしてあげると、同じbookでも買ったのか売ったのかがわかるようになります。

booksを取りたいときは、user.bought_booksなどにしてあげれば、買った本の一覧が取れます。

soldもまた然り。


source

class_nameと機能はほぼ同じ。ですが強いていうならば、throughを使うような中間テーブルがある際には

source、一対多のような中間テーブルを使わない場合は、class_nameが使われる。


foreign_key

日本語では外部キー、別テーブルの参照idを指定することができます。

先ほどの例を使いますが、

usersテーブル
booksテーブル

id
id

name
title

user_id

                      
author_id

それぞれこんなカラムを持っていたとします。今回はuserモデルの他にauthorモデルがあるとします。


user.rb

has_many :books



book.rb

belongs_to :user


何もないただの一対多ですと上のようにしますね。こうするとbooksテーブルにあるuser_idと合致するidをusersテーブルから持ってくるということができます。これはrailsが自動的にmodel名と一致するidを取りに行ってくれるからできることです。今回でいえば、user_idとUserモデルは同じuserという単語を利用していますよね。

これにあえて、userテーブルに存在しているidとauthor_idを一致させるようにする場合。。。。


user.rb

has_many :books, foreign_key => "author_id"



book.rb

belongs_to :user


ここで外部キーが出てきます。外部キーを明示してあげることでその名前のidをuserから取りに行きます。

実はアソシエーションの際には通常の場合でも、has_manyやbelongs_toの後にはforeign_keyが省略されています。このforeign_keyはあえて指定することで、外部キーを示すことができます。


through

中間テーブルが複数ある場合に利用します。sourceと一緒に出てくることが多いです。

今回は少し例を変えて、多対多で中間テーブルが複数ある場合を考えましょう。

複数のuserと複数のbookがあり、userは複数の本をいいねでき、本もまた複数の人からいいねをもらえる。

また、別経路でuserは本を複数書き、共同執筆で一つの本が複数のuserを持てるとします。

そうなると、userからbookを取りに行く場合、どちらの中間テーブルから取りに行けば良いかわかりません。

throughオプションで中間テーブルを指定すれば、経路を決めることができます。

これからも他に学ぶので追加予定です。