2011-09-10 39 views
1

我有一個類用於包含屬性類型的選擇菜單選項。它工作正常。但是,我需要能夠驗證選擇並根據所選選項執行特定的邏輯。這需要發生在我的Ruby代碼和JavaScript中。Ruby on Rails:基於選定菜單執行邏輯

這裏是有問題的類:

class PropertyTypes 

    def self.[](id) 
     @@types[id] 
    end 

    def self.options_for_select 
    @@for_select 
    end 

    private 
    @@types = { 
      1 => "Residential", 
      2 => "Commercial", 
      3 => "Land", 
      4 => "Multi-Family", 
      5 => "Retail", 
      6 => "Shopping Center", 
      7 => "Industrial", 
      8 => "Self Storage", 
      9 => "Office", 
      10 => "Hospitality" 
    } 

    @@for_select = @@types.each_pair.map{|id, display_name| [display_name, id]} 
end 

什麼是驗證選擇的最佳方式?我需要執行特定的邏輯並根據每種類型的屬性類型顯示用戶界面元素。

由於我存儲的ID,我會驗證該ID是一個特定的屬性類型。喜歡的東西:

PropertyTypes.isResidential?(id) 

那麼這種方法應該是這樣的:

def self.isResidential?(id) 
    @@types[id] == "Residential" 
end 

但現在我複製字符串「住宅」。

對於JavaScript,我假設我會做一個ajax回調模型以保持驗證碼DRY,但這看起來好像過度殺人。

我是否需要爲每種屬性類型手動創建驗證方法,還是可以使用define_method?

這似乎很基本,但我很困惑,並燒燬了這個問題。

感謝

=== 這裏是我的解決方案:

class << self 
@@types.values.each do |v| 
    # need to remove any spaces or hashes from the found property type 
    v = v.downcase().gsub(/\W+/, '') 

    define_method "is_#{v}?", do |i| 
    type_name = @@types[i] 
    return false if type_name == nil #in case a bogus index is passed in 
    type_name = type_name.downcase().gsub(/\W+/, '') 
    type_name == v 
    end 
end 
end 

回答

0

在Ruby方面你也可以使用這樣的動態定義這些方法:

class << self 
    @@types.values.each do |v| 
    define_method "is_#{v}?", do |i| 
     @@types[i] == v 
    end 
    end 
end 
+0

真棒!我嘗試過提到的兩種技術(define_missing和define_method),並使用define_method,因爲沒有必要處理respond_to?方法。 – tollbooth

+0

這是一篇關於使用[method_missing]的好文章(http://stackoverflow.com/questions/291132/method-missing-gotchas-in-ruby) – tollbooth

1

這聽起來像你可以從一些Ruby的元編程中受益。嘗試使用Google搜索「ruby method_missing」。你也許可以做線沿線的髒東西很快&:

class PropertyTypes 
def method_missing(meth, *args, &block) 
    if meth.to_s =~ /^is_(.+)\?$/ 
     @@types[args.first] == $1 
    else 
     super 
    end 
    end 
end