Ruby on Rails: Execute Logic Based on Selected Menu
I have a class that I use to contain select menu options for property types. It works fine. However, I need to be able to verify the selection and perform specific logic based on the selected option. This needs to happen in my Ruby code and in JavaScript.
Here is the class in question:
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",
开发者_JS百科 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
What is the best way to verify the selection? I need to perform specific logic and display user interface elements based on each type of property type.
Since I am storing the id, I would be verifying that the id is a particular property type. Something like:
PropertyTypes.isResidential?(id)
Then this method would look like this:
def self.isResidential?(id)
@@types[id] == "Residential"
end
But now I am duplicating the string "Residential".
For JavaScript, I assume I would make an ajax call back to the model to keep the verification code DRY, but this seems like over kill.
Do I need to manually create a verification method for each property type or can I use define_method?
This seems so basic yet I am confused and burned out on this problem.
Thanks
=== Here's my solution:
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
It sounds like you can benefit from some Ruby meta-programming. Try googling "ruby method_missing". You can probably do something quick & dirty along the lines of:
class PropertyTypes
def method_missing(meth, *args, &block)
if meth.to_s =~ /^is_(.+)\?$/
@@types[args.first] == $1
else
super
end
end
end
On the ruby side you could also use something like this to define dynamically these methods:
class << self
@@types.values.each do |v|
define_method "is_#{v}?", do |i|
@@types[i] == v
end
end
end
精彩评论