2009-07-24 77 views
3

我在我的數據庫架構中有一個整數的項目,它們被設置爲與項目相關的特定數字。例如,一個名爲appointment_type的列的值可以設置爲0 =未知,1 =醫療,3 =試用等等......我不想在我的rails代碼中使用幻數,而更喜歡類似Enum的解決方案使代碼更易於維護和閱讀。此外,有多個表具有此appointment_type列,所以我希望能夠使用「枚舉」來解決其他列。Rails全局枚舉?

我想有一個像項目的全局枚舉,因爲我需要訪問我的模型,控制器和視圖。我可能不太可能需要在我的模型中訪問它,但肯定在控制器和視圖中。

有沒有很好的方法來處理這個問題?

回答

4

它可能不太可能,我需要 訪問它在我的模型,但肯定 內的控制器和視圖。

確定嗎?當您談論數據庫和模式時,您正在討論應用程序的模型部分。 我認爲存儲這些變量的最佳位置就是使用它們的模型。

如果這些變量屬於一個單一的模式,你可以在模型本身直接存儲他們:

class Item < ActiveRecord::Base 
    STATUS_UNKNOWN = 0 
    STATUS_MEDICAL = 3 
end 

那麼你可以參考內部和模型範圍以外的值

class Item 
    def my_method 
    STATUS_UNKNOWN 
    end 
end 

Item::STATUS_UNKNOWN # => 0 
Item.new.my_method # => 0 

當是值的枚舉,Rubyists通常使用散列或數組。

class Item 
    AVAILABLE_STATUSES = { :unkwnown => 0, :medical => 3 } 

    def self.statuses 
    self.AVAILABLE_STATUSES.keys.sort 
    end 

    def self.status_value(key) 
    self.AVAILABLE_STATUSES[:key] 
    end 

end 

Item::AVAILABLE_STATUS # => { :unkwnown => 0, :medical => 3 } 
Item.statuses # => [:medical, :unkwnown] 
Item.status_value(:medical) # => 3 

如果多個模型共享相同的邏輯,可以將它放在模塊中,並將模塊混合到需要它的所有模型中。

+0

我會在哪裏把模塊?在lib /? – intargc 2009-07-24 20:35:57

+0

您可以使用/ lib,但我通常更喜歡使用所有控制器/模型自定義混合創建一個名爲/ apps/concern的文件夾。 – 2009-07-24 21:43:40

0

我的通話將提出,在相關模型

1

這個代碼可以幫助你......

首先,在lib文件夾命名一個文件:

integer_to_enum.rb 

在該文件把這個代碼:

module IntegerToEnum 

    class << self 

    def included(klass) 
     klass.extend(ModelClassMethods) 
    end 

    end 

    module ModelClassMethods 

    def fields_to_enum(options={}) 
     class_eval <<-end_eval 
     def set_enum_options 
      @enum_options = #{options.inspect} 
     end 
     end_eval 

     options.each_pair do |k,v| 
     class_eval <<-end_eval 
      def #{k.to_s} 
      self.set_enum_options 
      @enum_options[:#{k.to_s}][read_attribute(:#{k.to_s}).to_i] 
      end 

      def #{k.to_s}=(v) 
      self.set_enum_options 
      unless @enum_options[:#{k.to_s}].include?(v) 
       return false 
      end 

      write_attribute(:#{k.to_s}, @enum_options[:#{k.to_s}].index(v)) 
      @#{k.to_s} 
      end 
     end_eval 
     end 
    end 
    end 

end 

在enviroment.rb,把這個在底部,'結束「

ActiveRecord::Base.send :include, IntegerToEnum 

而在去年,在你想要的模型 '翻譯' 的整型字段放:

class YourModel < ActiveRecord::Base 

    fields_to_enum :appointment_type => [:unknown, :medical, :trial], :other_field_type => [:type_a, :type_b, :type_c] 

end 

有了這個,你可以這樣做:

m = YourModel.find(1) 
m.appointment_type #=> :unknown 
m.appointment_type = :trial #=> :trial 
m.save #=> and this will save with the index value of the array definition, since ':trial' is in the 3er position, the sql resulting will save with this number 

和所有..希望對您有所幫助

0

您可以擁有一張表,其中包含所有這些信息並緩存初始表選擇環境負載。

這樣,您甚至可以在其他表上實現appointment_types表和appointment_type_id表之間的參照完整性。