2012-02-05 62 views
0

我有應用程序,其中用戶可以有幾個不同的配置文件之一。一些配置文件數據總是相同的(如姓名,性別等)。其他領域可能會有所不同(例如,醫生可以擁有關於他自己的許可證編號和文字,而患者可以擁有電話號碼等)。導軌和多個配置文件

我發現了一種方法,很適合,但仍有一些疑問。我的方法的要點如下:

  1. 用戶模型中包含了很多具體的系統數據,通過制定控制和has_one :person

  2. Person模型包含常見的配置文件數據和belongs_to :profile, :polymorphic => true

  3. Doctor/Patient/Admin/etc包含更具體的配置文件數據和has_one :person, :as => :profile

通過這種方法,我可以親自模型簡單檢查:

def doctor? self.profile_type == 'Doctor' end

但有幾件事情不給我休息一下。

首先是表現。這種方法需要大量額外的連接。例如,爲了同時閱讀醫生的許可證號碼,姓名和電子郵件,它將生成2個額外的連接。

第二個是針對個人資料模型(即Doctor)和個人/用戶模型的不同ID。當ID = 1的用戶與不同的ID具有Patient關係時,會出現這樣的情況,但對於所有這些關聯的模型具有相同的ID是合乎邏輯的。

也許你們會看到這種方法更多的陷阱?我的情況有沒有更好的解決方案?

回答

3

你有四種基本模式,你可以在這裏使用,可能工作。

Omnirecord

在這種模式下,你有一個記錄所有可能的字段,然後使用STI配置文件類型之間進行區分。這是最簡單的實現,但看起來最混亂,因爲很少有人會填充所有字段。請記住,NULL字符串字段不佔用大量數據庫空間,通常每列一位,所以有很多數據庫空間並不是什麼大不了的。

可選加入

在這個模型中創建了一些可能存在的聯繫,以不同的配置文件類型,如doctor_profile_id鏈接到DoctorProfile,patient_profile_id鏈接到PatientProfile,等等。由於每個關係都是在特定字段中拼寫出來的,所以如果您願意,甚至可以實施外鍵約束,並且索引編制非常簡單。當單個記錄需要多個不同的配置文件與其關聯時,這可以派上用場,例如,病人也是醫生。

多態性加入

在這種模式下,你使用:polymorphic選項,就像你建議的鏈接到一個特定配置文件類型和文件ID。索引更復雜,外鍵是不可能的。您也僅限於擁有一個且只有一個配置文件。這些往往是作爲一個起點,但是當您獲得醫生+患者的要求時,可能會證明這是麻煩事。

鍵/值存儲

在這種模式下,你放棄所有的努力舉辦東西變成單數紀錄,而是建立一個相關的ProfileField和ProfileValue表。 ProfileField標識哪些字段可用於哪些類型的配置文件,如標籤,允許的值,數據類型等,而ProfileValue用於存儲特定配置文件的特定值。

class User < ActiveRecord::Base 
    has_many :profile_fields 
end 

class ProfileField < ActiveRecord::Base 
    has_many :profile_values 
end 

class ProfileValue < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :profile_field 
end 

由於這一個是敞開的,你可以允許網站管理員重新定義需要什麼樣的領域,增加新的領域,等等,而無需進行架構更改。

+0

感謝您的迴應!根據你的建議,多態對我來說仍然是最乾淨的方法。我不打算在用戶同時擁有多個配置文件的情況下。但我同意,會有一些索引問題。看起來沒有理想的解決方案。 – tipugin 2012-02-06 04:34:23

+1

理想的解決方案是可以工作的,並且不會在將來給您帶來麻煩,就這些! – tadman 2012-02-06 14:36:18