Ruby on Rails: выполнение логики на основе выбранного меню - PullRequest
1 голос
/ 10 сентября 2011

У меня есть класс, который я использую для выбора опций меню для типов свойств. Работает нормально. Однако мне нужно иметь возможность проверить выбор и выполнить определенную логику на основе выбранной опции. Это должно происходить в моем коде 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

Как лучше всего проверить выбор? Мне нужно выполнить определенную логику и отобразить элементы пользовательского интерфейса на основе каждого типа типа свойства.

Так как я храню идентификатор, я бы проверил, является ли идентификатор конкретным типом свойства. Что-то вроде:

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

Ответы [ 2 ]

1 голос
/ 10 сентября 2011

Похоже, вы можете извлечь выгоду из некоторого метапрограммирования 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
0 голосов
/ 10 сентября 2011

На стороне ruby ​​вы также можете использовать что-то подобное для динамического определения этих методов:

class << self
  @@types.values.each do |v|
    define_method "is_#{v}?", do |i|
      @@types[i] == v
    end
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...