2012-03-06 95 views
3

我有一個用戶模型,它有一個狀態。該狀態可以是這些:「未經驗證的」,「主動」,「刪除」]Ruby on Rails ActiveRecord:我應該如何存儲對象的狀態?

什麼是存儲在數據庫中的對象的狀態的最好方法?

我應該創建三個布爾字段嗎?這不會有什麼意義,因爲我可能想要輕鬆擴展狀態的數量,並且只有一個狀態可以同時爲「真」。

我應該使用state_machine寶石只爲固定值的簡單切換?

或有任何其他常見的方式,最好的做法,或者一個簡單的寶石這樣的工作嗎?

回答

17

一個非常簡單的解決方案,我已經使用這個:

在遷移

add_column :users, :state, :string 

在您的模特兒

class User < ActiveRecord::Base 

    STATES = %w{ unverified active deleted } 

    STATES.each do |state| 
    define_method("#{state}?") do 
     self.state == state 
    end 

    define_method("#{state}!") do 
     self.update_attribute(:state, state) 
    end 
    end 
end 

然後就可以調用

@user.active? # => returns true/false 

或者

@user.active! # => sets the users state to active 
1

我會將它保留爲零,'激活','刪除'。如果您希望在切換狀態時有額外的進程掛鉤,例如發送的電子郵件,那麼state_machine gem會很有用。另外,如果您希望有其他分析功能,例如某人從未驗證狀態變爲活動狀態,可能會有用'active_on_date',並在轉換髮生時將其存儲爲日期時間。

2

您可以使用一個枚舉類型的狀態存儲爲一個簡單的整數。我通常使用active_enum寶石來簡化。這將是這個樣子

class User 

    # An enumerated type representing the current state of the user 
    enumerate :state do 
    value name: "unverified" 
    value name: "active" 
    value name: "deleted" 
    end 

end 

這將允許你檢查狀態以下列方式

# check if active 
user.state?(:active) 

只要確保你有一個名爲state一個整數字段(或任何你想呼叫的枚舉類型)在User表中。

有關詳細信息,請參閱gem documentation

+0

我真的很喜歡這個實現,除了ID不會以參照完整性存儲在數據庫中。 – fregas 2012-03-06 21:40:53

+0

這是一個很好的觀點。除了實現一個'''State''模型的解決方案,這是正確的嗎? – 2012-03-06 22:08:22

1

請勿使用布爾字段。

如果國家的名字就像一個「鑰匙」,並不會改變,你可以將它們存儲在數據庫中的文本字段。只需使用

add_column :users, :state, :string 

添加遷移當您保存對象時,它會採取user.state和符號存儲爲「未驗證」,「活動」等

如果狀態是一個字符串可能會在某個時間點重新命名,那麼您可以將它們放入自己的表格中,併爲它們製作自己的主動記錄模型,而不是使用符號。做一個

rails g model State name:string 

軌道將創建一個模型文件和他們的遷移。然後用這個改變遷移:

add_column :users, :state_id, :integer 

您可以使用未經驗證,活躍等直接在SQL或通過種子或現有的遷移填充狀態列表。如果需要,您也可以在它們之間創建一個外鍵。

然後在你的代碼,以設置狀態,你這樣做:

user.state = State.find_by_name(:unverified) 
+0

您確定要將'state'列存儲爲'text'嗎?它看起來好像是一個「字符串」。 – jaredonline 2012-03-06 20:49:29

+0

是的,你是對的。我正是這個意思。現在編輯。 – fregas 2012-03-06 21:21:29

3

如果你正在使用Rails3中使用MySQL數據庫可以使用enum_column。它提供了一個:enum列何時用於遷移以及驗證方法。它還提供了一個enum_select視圖助手。

相關問題