2012-07-20 55 views
3

我對rails中的STI有些困惑。帶有CRUD和Rails表單的單表繼承

我的情況: 我有一個Contact模型具有descriptiondata字符串字段,以存儲如電話,傳真,電子郵件一些接觸等

現在,當我有一些具體的接觸式一樣的電話號碼電子郵件地址我想用不同的方式覆蓋數據格式,我想對輸出進行一些不同的格式化。

我決定使用STI,因爲所有的模型都有相同的數據,只有不同的行爲。我還有一些關於表單和CRUD操作的問題,因爲我不想違反Rails約定。

  1. 如何在模型類型的窗體中創建下拉列表?我應該硬編碼還是有更多的自動化方式?

  2. 如何創建記錄?我是否應該使用switch聲明並根據收到的類型創建相應實例的新模型?

  3. 如果我要更改模型類型,我應該如何更新它?將對象轉換爲新類?或者創建一個新對象並銷燬前一個對象?

我會非常感謝您的幫助!

回答

2
  1. 是的,應該做一個硬核,因爲沒有STI型號的默認存儲。
  2. 一般來說,是的。但是使用Rails,你可以使用camelize.constantize從字符串中獲得類。另一種方法是使用父級模型,並手動設置type字段。與STI一樣,所有記錄都在同一個表中,然後所有記錄都是父類。
  3. 如果您想更新,只需更新type字段。然後你可以重新查詢來強制Rails獲取不同類型的新對象。
+0

謝謝您的回覆。但是,如果我只設置一個類型字段,驗證是否適用於特定的模型? – Uko 2012-07-20 12:01:45

+2

@Uko是的,如果你做'@model = type.camelize.contantize.new(params [:model])' – 2012-07-20 14:33:17

+0

哇,真的很好。還有一件事。我應該如何處理更新?我應該像'@ model.becomes(type.camelize.contantize)'然後'@ model.update_attributes(params [:model])'做些什麼? – Uko 2012-07-20 16:54:05

0

您可以創建這樣一個模型:

Type < ActiveRecord::Base 
    has_many :contacts 
end 

您可以使用此命令rails g model Type name:string,在您的聯繫人添加type_id列和遷移數據庫。

末更改您的聯繫的模式是這樣的:現在

Contact < ActiveRecord::Base 
    belongs_to :type 
end 

,在你的表格,你可以這樣做:

select("type", "type_id", Type.all.collect {|t| [ t.name, t.id ] }, { :include_blank => true }) 

應該解決您的問題。

現在你可以做這樣的事情:

@emails = Type.find_by_name('email').contacts 

或者使用範圍。

+0

謝謝你這個sujjestion,我想過這個選項,但我認爲STI是一個更好的設計策略,因爲我有完全相同的數據,只需要不同的驗證和格式化等。使用STI驗證將根據模型本身來完成,並且在您的解決方案中,我將需要使用'switch'語句使用一些預驗證回調 – Uko 2012-07-20 12:07:11