我要活下去!!!
以前不敢問問題,到現在看到什麼就想問,根本忘了先_查資料_,再發問。
問問題前,應該先查資料,再把不了解的濃縮成人話(當然這很難!!!
難的地方不是發問,而是要很讓人聽懂。
以下是得到的解答,透過我的大腦,解析出的人話(?
或許不對,不清楚,再麻煩大家包涵或者直接幹瞧我喔^_<
單一表格繼承STI(Single-table inheritance)
如何將物件導向中的繼承概念,對應到關聯式資料庫的設計,是個大哉問。Rails內建了其中最簡單的一個解法,只用一個資料表儲存繼承體系中的物件,搭配一個type
欄位用來指名這筆資料的類別名稱。要開啟STI功能,依照慣例只要有一個欄位叫做type
,型態字串即可
比方說:我有一個 Animal Model
,為了要有繼承功能,我們新增 type
這個欄位。
1 2 3 4 5 6 7 | def change create_table :animals do |t| t.string :name t.string :type t.timestamps null: false end end |
那要被繼承的 Dog、Cat兩個 Model就不用在建立表格欄位了。
1 2 3 4 5 6 7 8 | class Animal < ActiveRecord::Base end class Dog < Animal end class Cat < Animal end |
這時候他們都繼承了Animal這個爸爸,爸爸有什麼,他們就有什麼了。
但缺點就是,爸爸有的,你不一定需要,但你還是得擁有那些欄位。
如果要關閉的話就在爸爸身上加上 self.abstract_class = true
多型關聯(Polymorphic Associations)
多型關連(Polymorphic Associations)可以讓一個 Model 不一定關連到某一個特定的 Model,秘訣在於除了整數的_id外部鍵之外,再加一個字串的_type欄位說明是哪一種Model。
多型關聯,當你有某種事情需求,已經有Model在做那件事情時。
我在其他Model,也想使用到那件事情時,我就不用在另外建立Model,來做一樣的事情了。
以上想用自己的話表達簡單一點,但覺得太攏統,太模糊了
以下引用文件
例如一個Comment model,我們可以透過多型關連讓它belongs_to到各種不同的 Model上,假設我們已經有了Article與Photo這兩個Model,然後我們希望這兩個Model都可以被留言。不用多型關連的話,你得分別建立ArticleComment和PhotoComment的model。用多型關連的話,無論有多少種需要被留言的Model,只需要一個Comment model即可:
rails g model comment content:text commentable_id:integer commentable_type
產生出
1 2 3 4 5 6 7 8 9 10 11 | class CreateComments < ActiveRecord::Migration[5.1] def change create_table :comments do |t| t.text :content t.integer :commentable_id t.string :commentable_type t.timestamps end end end |
這個Migration檔案中,我們用content這個欄位來儲存留言的內容,commentable_id用來儲存被留言的物件的id而commentable_type則用來儲存被留言物件的種類,以這個例子來說被留言的對象就是Article與Photo這兩種Model,這個Migration檔案也可以改寫成下面這樣:
1 2 3 4 5 6 7 8 9 10 11 | class CreateComments < ActiveRecord::Migration[5.1] def change create_table :comments do |t| t.text :content t.belongs_to :commentable, :polymorphic => true #同時會幫你產生出[:commentable_id, :commentable_type] t.timestamps end end end |
這時就必須指定關聯
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class Comment < ApplicationRecord belongs_to :commentable, :polymorphic => true #透過true來將此關聯指定是多型關聯 end class Article < ApplicationRecord has_many :comments, :as => :commentable #我們用:as來指定 :commentable這個參數作為多型關聯的接口 #:as是什麼?可以看has_one or has_many API end class Photo < ApplicationRecord has_many :comments, :as => :commentable end |
接下來可以透過關聯來新增留言
1 2 3 4 5 6 7 8 9 10 11 | article = Article.first #透過關連新增留言 comment = article.comments.create(:content => "First Comment") #你可以發現 Rails 很聰明的幫我們指定了被留言物件的種類和id comment.commentable_type => "Article" comment.commentable_id => 1 #也可以透過 commentable 反向回查關連的物件 comment.commentable => #<Article id: 1, ....> |
簡單來說,我有一個留言的model了,我在文章與照片都想要可以留言,既然已經有model在做這件事了,
我們就使用多型關聯來連到那裡去。就不用說還需要再另外建立什麼了。
文章引用參考至:
https://ihower.tw/rails/activerecord-relationships.html
https://ihower.tw/rails/activerecord-others.html
-W