2013-05-18 39 views
2

rails不提供ENUM類型,但我確實需要一個只能接受五個值的數據成員。此外,我希望它能自動與Rails Forms Helper集成:select_tag
什麼是我的情況正確的解決方案?rails替代枚舉和查看集成

P.S,我寧願不使用外部插件,如果內置和整潔的解決方案存在。

+1

你是什麼意思的「自動集成」的形式助手?爲了做到這一點,你需要創建一個關聯。建立一個不是實際表的關聯是可能的,但是提供允許值的列表可能更容易一些嗎? –

+0

所以我可以在控制器中執行:@forum = Forum.new(params [:forum])並像其他字段一樣自動讀取它。 –

+1

你還可以;這與定義值的位置無關:它只是表單中的字符串。 –

回答

3

我保持這樣的功能儘可能接近它的使用位置。

如果值由單個模型中使用,只是讓他們在模型中,例如,如果用戶有一定可能的類型,只有那些類型,它可能看起來像:

class User < ActiveRecord::Base 
    TYPES = %w{guest, paid, admin} 

    # Plus validation on the `type` field. 
    # Maybe plus a setter override that also validates. 
end 

當你需要參考這些類型的其他地方一樣,如允許值的選擇:

User::TYPES 

有許多解決這個寶貴的調整,如提供裝飾,使他們「人類可讀」(大寫,間距,等等)或元編程方法來允許像這樣的東西:

user.is_guest? # Or... 
user.make_guest! # Or... 
user.guest! 

我用我自己的小寶石這一功能,因爲它往往是一個完全成熟的關聯實在太多,並且不提供價值的情況下。它允許了諸如:利用尖端

class User < ActiveRecord::Base 
    simple_enum :user_type, %w{guest, paid, admin} 
end 
0

您可以輕鬆地定義枚舉作爲幫手ApplicationHelper

class ApplicationHelper 
    def select_range 
    %w{"a", "b", "c", "d", "e"} 
    end 
end 

然後在視圖中,您可以撥打select_range自由。

+0

我會爭辯說,如果枚舉直接綁定到一個特定的模型或模型,它屬於其他地方而不是幫助者。無論是在模型中,還是在混合模型中。 –

+0

@DaveNewton,我明白你的觀點,但不能從問題中看出來。如果涉及模型,只要提供了詳細信息,它仍然可以在幫助程序中定義,或作爲模型中的方法。 –

+2

是的,它*可以*定義在助手中,或者定義爲視圖中的直接列表,或者......但是*爲什麼*你會在其他地方定義它,而不是在它使用的模型中定義它?將其保留在與其相關的類本地的地方將被視爲最佳實踐(例如,參見Rails反模式書)。允許的值明確地與模型綁定,並且IMO的依賴性也應該在代碼中明確。由於您還需要驗證輸入值,以保持它們在模型中的任何位置,或者在混合模式中混淆事物。 –

2

從這個blog post,它提供了一個非常簡單的方法。 您可以在您的模型上設置,然後在您的控制器或視圖中使用它。 在這種情況下,它將使用整數映射狀態。

STATUS = { pending: 0, active: 1, inactive: 2, deleted: 3 } 

def status 
    STATUS.key(read_attribute(:status)) 
end 

def status=(s) 
    write_attribute(:status, STATUS[s]) 
end 
+1

這種方法有兩個好處。至少對我而言,最大的* dis * -advantage是,如果直接查看數據,數據庫會變得不易讀。 –

1

Rails 4.1擁有枚舉。我剛剛升級到測試版,它的功能就像一個魅力!

http://edgeapi.rubyonrails.org/classes/ActiveRecord/Enum.html

我試過active_enum的寶石,這是偉大的,但它與軌道4.從聖保羅解決方案的工作非常好,你可以提取枚舉到一個問題,如果你想不兼容,但它只是開始對我來說太重了,所以我寧願升級!