many to many association by one join tabel with 3 foreign keys

延續上一篇問題

建立滿足以下關係的Table Associations

  1. User can create a tag for a book.
  2. According to a given tag, return book list.
  3. According to a given book, return tag list.

這次只用一個Join Table但包含了3個FK來實作

建立4個Table

schema
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
create_table "books", force: :cascade do |t|
t.string "title"
end

create_table "tags", force: :cascade do |t|
t.text "label"
end

create_table "user_book_tags", force: :cascade do |t|
t.integer "user_id"
t.integer "book_id"
t.integer "tag_id"
end

create_table "users", force: :cascade do |t|
t.string "name"
end

其中user_book_tags包含了user_id, book_id, tag_id,3個Foreign key

設定Model Associations

User
1
2
3
4
class  < ActiveRecord::Base
has_many :user_book_tags
has_many :tags, through: :user_book_tags
end
Book
1
2
3
4
class Book < ActiveRecord::Base
has_many :user_book_tags
has_many :tags, through: :user_book_tags
end
Tag
1
2
3
4
5
6
class Tag < ActiveRecord::Base
has_many :user_book_tags
has_many :users, through: :user_book_tags

has_many :books, through: :user_book_tags
end
UserBookTag
1
2
3
4
5
class UserBookTag < ActiveRecord::Base
belongs_to :user
belongs_to :book
belongs_to :tag
end

再來是在Rails Console裡測試

1
2
3
4
5
6
7
8
9
10
11

> User.create(name: "Tomo")
> Book.create(title: "Ruby")
> Tag.create(label: "good book")
> UserBookTag.create(user: User.first, book: Book.first, tag: Tag.first)

# test associations
> User.first.tags
> Book.first.tags
> Tag.first.users
> Tag.first.books

上一次的方法相比,少建立一個Table。