方法:建一個新的 table 取代原先兩個;在新 table 使用 新table名able_type 這個欄位,來判讀是原先哪一個 table;再用 新table名able_id 判斷其id
範例:
有兩個 model ,post 和 comment,為做其 vote 功能,須各別新增 PostVote 和 CommentVote model。但這兩個mobel的欄位是有重覆,各別是
post table : vote post_id user_id
comment table : vote comment_id user_id
因此新增一個table/model取代這兩個
1, 生出migration 檔
$ rails g migration create_votes
class CreateVotes < ActiveRecord::Migration
def change
create_table :votes do |t|
t.boolean :vote
t.integer :user_id
t.string :voteable_type
t.integer :voteable_id
t.timestamps
end
end
end
$ rake db:migrate
2, 在 model 建立關聯
# + app/models/vote.rb
class Vote < ActiveRecord::Base
belongs_to :user, foreign_key: :user_id
belongs_to :voteable, polymorphic: true
end
# app/models/psot.rb
class Post < ActiveRecord::Base
has_many :votes, as: :voteable
end
class Comment < ActiveRecord::Base
has_many :votes, as: :voteable
end
3, 去 rails console 測試
post = Post.first
post.votes
Vote
vote = vote.create(vote: true, user_id: 1)
vote
沒問題就表示建立的關聯是對的
多型關連大致是這樣。
有沒有覺得又很像副程式?一種 function 的概念。大概是 Ruby 裡任何東西都是物件,所以可以把資料庫像副程式一樣搞;當然也是因為ORM,資料庫物件化的緣故。
參考:
http://rails.ruby.tw/association_basics.html
台大資工Rails 課程上課筆記