アソシエーションで利用するオプションメモ
最近開発していて、利用するオプションが増えてきたので、一度まとめておこうかと思います。
メモ書きですのでご了承。。。。
class_name
一つのモデルに対して、二つのアソシエーション経路を組む場合に多用します。
二つアソシエーションを組む場合は、経路を指定する必要がありますが、モデルが一つのため、
別経路なのに取りに行くモデルが同じということが起こります。これを防ぐために、class_nameがあります。
これのおかげで便宜的にモデルを二つに分けることができ、実際は一つのモデルを見に行くということができます。
例えば。。。。
本を売り買いできるサービスがあったとして、自分が売った本一覧と買った本一覧を見ることができるとします。
単なるアソシエーション(user.booksとか)だと、userがそのbookに対してどのようなアクションを行ったのかが判別できません。
なのでclass_nameを利用して、経路を二つ用意してやります。
user1に対してbook多になります。
has_many :bought_book, class_name: "Book"
has_many :sold_book, class_name: "Book"
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モデルがあるとします。
has_many :books
belongs_to :user
何もないただの一対多ですと上のようにしますね。こうするとbooksテーブルにあるuser_idと合致するidをusersテーブルから持ってくるということができます。これはrailsが自動的にmodel名と一致するidを取りに行ってくれるからできることです。今回でいえば、user_idとUserモデルは同じuserという単語を利用していますよね。
これにあえて、userテーブルに存在しているidとauthor_idを一致させるようにする場合。。。。
has_many :books, foreign_key => "author_id"
belongs_to :user
ここで外部キーが出てきます。外部キーを明示してあげることでその名前のidをuserから取りに行きます。
実はアソシエーションの際には通常の場合でも、has_manyやbelongs_toの後にはforeign_keyが省略されています。このforeign_keyはあえて指定することで、外部キーを示すことができます。
through
中間テーブルが複数ある場合に利用します。sourceと一緒に出てくることが多いです。
今回は少し例を変えて、多対多で中間テーブルが複数ある場合を考えましょう。
複数のuserと複数のbookがあり、userは複数の本をいいねでき、本もまた複数の人からいいねをもらえる。
また、別経路でuserは本を複数書き、共同執筆で一つの本が複数のuserを持てるとします。
そうなると、userからbookを取りに行く場合、どちらの中間テーブルから取りに行けば良いかわかりません。
throughオプションで中間テーブルを指定すれば、経路を決めることができます。
個人開発をされている方へ
Moverというプロダクトを開発しています。登録していただくと、開発したプロダクトのテスト利用を依頼し、フィードバックをもらうことができます。自分のプロダクトを公開して個人開発を加速させましょう!! 現在僕のアカウントも登録されているので、そちらにテスト利用依頼をいただければ実際に使ってみた感想などをお送りさせて頂きます。(アドバイスなどではなく、一人のユーザーとしての感想となります。) もちろん無料です。
https://mover-web.herokuapp.com/