2014-01-17 149 views
1

如何處理rails中的枚舉?我已經使用了這個,但沒有找到任何干淨的解決方案。到目前爲止,我已經在使用interaction_type_id的模型中提出了以下關注。這是我在數據庫枚舉表中的外鍵。使用這種方法,我沒有給所有在我的代碼IDS使用,但保存該涉及interact_type一個對象的時候,我可以說如何處理rails枚舉?

myobject.interaction_type = :file_download 

這可以再用,因爲關注正確的ID堅持的數據庫(請參閱下面的關注 - 包含在使用枚舉的模型中)將返回正確的ID。

module InteractionTypeEnum 
    extend ActiveSupport::Concern 

    included do 
    INTERACTION_TYPE = { file_download: 1, email: 2, telesales: 3, registration: 4, enrolment: 5 } 
    end 

    def interaction_type 
    INTERACTION_TYPE.key(read_attribute(:interaction_type_id)).to_s.gsub('_',' ').capitalize 
    end 

    def interaction_type=(s) 
    write_attribute(:interaction_type_id, INTERACTION_TYPE[s]) 
    end 
end  

這只是感覺很重。必須有一種更簡單/更清潔的方式。現在當試圖爲此編寫測試時,它變得更加混亂。

希望在代碼和數據庫中枚舉的大多數原因是性能(代碼)和報告(數據庫)。

任何幫助表示讚賞。謝謝。

回答

1

我建議active_enum寶石。從自己的文件

例如,如果你有一個整數列名爲sex的類User

class User < ActiveRecord::Base 
    enumerate :sex do 
    value :name => 'Male' 
    value :name => 'Female' 
    end 
end 

,也可以定義在一個單獨的類枚舉:

class Sex < ActiveEnum::Base 
    value 1 => 'Male' 
    value 2 => 'Female' 
end 

class User < ActiveRecord::Base 
    enumerate :sex, :with => Sex 
end 

我喜歡它提供了抽象的功能,並且可以避免爲了存儲枚舉值而創建整個數據庫表。

+0

不錯的解決方案,但可以說現在將用戶存儲在數據庫中,並且您想通過後端訪問用戶的性別。你是說這應該作爲一個字符串存儲在數據庫中 - 男性,女性。如果你的枚舉集合增加到10個,並且在那之後不會改變,會發生什麼。你不希望這個信息在數據庫的表中嗎?在某些情況下,您還可能想要擴展枚舉以包含其他信息,例如排名/順序或說明。我看到這是如何有用和乾淨的,但它可能有點有限。 –

+0

它作爲一個整數存儲在數據庫中,並且比我在這裏複製粘貼的功能多得多(例如,您可以將擴展信息添加到您描述的枚舉中。)如果只是爲了更多地瞭解它,看看它是否適合你的目的,我建議給它一個去;我在多個項目中使用過它,從來沒有遇到任何問題。但當然,這不是唯一的解決方案(我相信也有其他枚舉寶石,或者您可以像其他答案一樣推出自己的枚舉類型),並且我沒有太多的投入,其他建議也可以工作。 – GMA

+0

我已經簽出github。看起來非常好,但它似乎不支持rails 4.當我在代碼中啓用config.extend_classes = [ActiveRecord :: Base]並嘗試運行rails控制檯時,我得到/Users/ryanme/.rvm/gems/ruby [email protected]_rails_4_0/gems/activerecord-4.0.2/lib/active_record/dynamic_matchers.rb:22:在'method_missing':未定義的方法'class_inheritable_accessor'爲ActiveRecord :: Base:Class(NoMethodError)--- ----從我讀過的class_inheritable_accessor已被棄用。 –

0

我使用下面的方法,說我有

class PersonInfo < ActiveRecord::Base 
    belongs_to :person_info_type 
end 

PersonInfoType是一個簡單的域表,將含有可能類型的信息。

然後我如下的代碼我的模型:

class PersonInfoType < ActiveRecord::Base 

    PHONE = 1 
    EMAIL = 2 
    URL = 3 

end 

我有一個種子填充與相應數據的數據庫。

所以分配當一些人信息可以這樣做

person.person_infos << PersonInfo.create(:info => 'http://www.some-url.com', :person_info_type_id => PersonInfoType::URL) 

該代碼然後可以進一步清理使用關係:

class PersonInfo 

    belongs_to :person_info_type 

    def self.phones 
    PersonInfo.where(:person_info_type_id => PersonInfoType::PHONE) 
    end 

end 

person.person_infos << PersonInfo.phones.create(:info => '555 12345')