Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Support ObjC style settings (ie setProperty:) and `sym` -> `method`

why? KVO looks for methods which respond to set<Something>. KVO seems to be broken in RubyMotion right now, but for the future?
  • Loading branch information...
commit 3de27b4ad1a8dba8e1d630453643a99d5b3f6707 1 parent 3fccd33
@clayallsopp authored
Showing with 45 additions and 14 deletions.
  1. +45 −14 lib/remote_model.rb
View
59 lib/remote_model.rb
@@ -111,7 +111,7 @@ def remote_model_methods
methods = []
[self.class.has_one, self.class.has_many, self.class.belongs_to].each {|fn_hash|
methods += fn_hash.collect {|sym, klass|
- [sym, (sym.to_s + "=:").to_sym]
+ [sym, (sym.to_s + "=:").to_sym, ("set" + sym.to_s.capitalize).to_sym]
}.flatten
}
methods + RemoteModule::RemoteModel::HTTP_METHODS
@@ -129,32 +129,34 @@ def respond_to?(symbol, include_private = false)
super
end
- def method_missing(sym, *args, &block)
+ def method_missing(method, *args, &block)
# Check for custom URLs
- if self.class.custom_urls.has_key? sym
- return self.class.custom_urls[sym].format(args && args[0], self)
+ if self.class.custom_urls.has_key? method
+ return self.class.custom_urls[method].format(args && args[0], self)
end
# has_one relationships
- if self.class.has_one.has_key?(sym) || self.class.belongs_to.has_key?(sym)
- return instance_variable_get("@" + sym.to_s)
- elsif (klass = self.class.has_one[sym.to_s[0..-2].to_sym] || klass = self.class.belongs_to[sym.to_s[0..-2].to_sym])
+ if self.class.has_one.has_key?(method) || self.class.belongs_to.has_key?(method)
+ return instance_variable_get("@" + method.to_s)
+ elsif (setter_vals = setter_klass(self.class.has_one, method) || setter_vals = setter_klass(self.class.belongs_to, method))
+ klass, hash_symbol = setter_vals
obj = args[0]
if obj.class != klass
obj = klass.new(obj)
end
- return instance_variable_set("@" + sym.to_s[0..-2], obj)
+ return instance_variable_set("@" + hash_symbol.to_s, obj)
end
# has_many relationships
- if self.class.has_many.has_key?(sym)
- ivar = "@" + sym.to_s
+ if self.class.has_many.has_key?(method)
+ ivar = "@" + method.to_s
if !instance_variable_defined? ivar
instance_variable_set(ivar, [])
end
return instance_variable_get ivar
- elsif (klass = self.class.has_many[sym.to_s[0..-2].to_sym])
- ivar = "@" + sym.to_s[0..-2]
+ elsif (setter_vals = setter_klass(self.class.has_many, method))
+ klass, hash_symbol = setter_vals
+ ivar = "@" + hash_symbol.to_s
if !instance_variable_defined? ivar
instance_variable_set(ivar, [])
end
@@ -180,11 +182,40 @@ def method_missing(sym, *args, &block)
end
# HTTP methods
- if RemoteModule::RemoteModel::HTTP_METHODS.member? sym
- return self.class.send(sym, *args, &block)
+ if RemoteModule::RemoteModel::HTTP_METHODS.member? method
+ return self.class.send(method, *args, &block)
end
super
end
+
+ private
+ # PARAMS For a given method symbol, look through the hash
+ # (which is a map of :symbol => Class)
+ # and see if that symbol applies to any keys.
+ # RETURNS an array [Klass, symbol] for which the original
+ # method symbol applies.
+ # EX
+ # setter_klass({:answers => Answer}, :answers=)
+ # => [Answer, :answers]
+ # setter_klass({:answers => Answer}, :setAnswers)
+ # => [Answer, :answers]
+ def setter_klass(hash, symbol)
+
+ # go ahead and guess it's of the form :symbol=:
+ hash_symbol = symbol.to_s[0..-2].to_sym
+
+ # if it's the ObjC style setSymbol, change it to that.
+ if symbol[0..2] == "set"
+ # handles camel case arguments. ex setSomeVariableLikeThis => some_variable_like_this
+ hash_symbol = symbol.to_s[3..-1].split(/([[:upper:]][[:lower:]]*)/).delete_if(&:empty?).map(&:downcase).join("_").to_sym
+ end
+
+ klass = hash[hash_symbol]
+ if klass.nil?
+ return nil
+ end
+ [klass, hash_symbol]
+ end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.