【问题标题】:Ruby on Rails: Execute Logic Based on Selected MenuRuby on Rails:根据选定菜单执行逻辑
【发布时间】:2011-11-14 10:18:22
【问题描述】:

我有一个类用于包含属性类型的选择菜单选项。它工作正常。但是,我需要能够验证选择并根据所选选项执行特定逻辑。这需要在我的 Ruby 代码和 JavaScript 中进行。

这是有问题的课程:

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

但现在我正在复制字符串“Residential”。

对于 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

【问题讨论】:

    标签: ruby-on-rails selection verification


    【解决方案1】:

    在 ruby​​ 方面,您还可以使用类似的东西来动态定义这些方法:

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

    【讨论】:

    • 太棒了!我尝试了提到的两种技术(define_missing 和define_method)并使用了define_method,因为不需要处理respond_to?方法。
    • 这是一篇关于与method_missing合作的好文章
    【解决方案2】:

    听起来您可以从一些 Ruby 元编程中受益。尝试谷歌搜索“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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-04
      • 1970-01-01
      • 2017-03-25
      • 1970-01-01
      • 2015-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多