I have a model that loads dynamically data from a REST API if a property is accessed and its property has no data:
class Issue
attr_accessor :ticket_title, :priority, :description
@ticket_title
@priority
@description
def priority
if !@priority.empty?
updateProperties()
end
@priority
end
def description
if !@description.empty?
updateProperties()
end
@description
end
def ticket_title
if !@ticket_title.empty?
updateProperties()
end
@ticket_title
end
def updateProperties
# loads all data from REST API
end
def initialize (hsh = {})
hsh.each { |key, value|
self.instance_variable_set("@#{key}", value)
}
end
end
There are two problems:
- If I initialize the model with
RedmineIssue.new :ticket_title => 'test', I dont want to the model to callupdateProperties, but somehow it does. - Is there a way to declare functions magically? I.e., if there is no real function try to run a meta function?
Well, here’s something for the “magic”. In your class, if you want to be able to get any part of a hash through a method named
get_whateverthekeyis(silly example, I know), you’d usemethod_missing:When the method is not defined, it goes to
method_missing. When that happens,method_missingdoes the requested operation on the hash, and then dynamically defines the method, so that next time it is a direct method call, meaning that it is much more efficient because the method already exists. This is somewhat akin the themethod_missingused by Ruby’s own OpenStruct.