lib/yammer/base.rb in yammer-client-0.1.1 vs lib/yammer/base.rb in yammer-client-0.1.2
- old
+ new
@@ -1,117 +1,148 @@
module Yammer
class Base
+ class << self
- def self.attr_accessor_deffered(*symbols)
- symbols.each do |key|
- fetchable_keys[key] = true
-
- define_method (key.to_s) do
- if self.class.fetchable_keys.has_key?(key) && !@attrs.has_key?(key) && @id
- load!
- end
- instance_variable_get("@#{key}")
+ # Returns the non-qualified class name
+ # @!scope class
+ def base_name
+ @base_name ||= begin
+ word = "#{name.split(/::/).last}"
+ word.gsub!(/::/, '/')
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
+ word.tr!("-", "_")
+ word.downcase!
+ word
end
+ end
- define_method ("#{key}=") do |value|
- if @attrs.fetch(key, false) && !new_record?
- @modified_attributes[key] = value
- else
- @attrs[key] = value
+ # Fetches JSON reprsentation for object model with provided `id`
+ # and returns a model instance with attributes
+ # @return [Yammer::Base]
+ # @param id [Integer]
+ # @!scope class
+ def get(id)
+ attrs = fetch(id)
+ attrs ? new(attrs) : nil
+ end
+
+
+ # @!scope class
+ def fetch(id)
+ return unless identity_map
+ attributes = identity_map.get("#{base_name}_#{id}")
+ unless attributes
+ result = Yammer.send("get_#{base_name}", id)
+ attributes = result.empty? ? nil : result.body
+ unless attributes.empty?
+ identity_map.put("#{base_name}_#{id}", attributes)
end
- instance_variable_set("@#{key}", value)
end
+ attributes
end
- end
- # @!scope class
- def self.fetchable_keys
- @fetchable_keys ||= {}
- return @fetchable_keys
- end
+ # @!scope class
+ def identity_map
+ @identity_map ||= Yammer::IdentityMap.new
+ end
- # @!scope class
- def self.identity_map
- @identity_map ||= Yammer::IdentityMap.new
- end
+ # Returns a hash of all attributes that are meant to trigger an HTTP request
+ # @!scope class
+ def fetchable_attrs
+ @fetchable_keys ||= {}
+ end
- # @!scope class
- def self.base_name
- word = "#{self.name.split(/::/).last}"
- word.gsub!(/::/, '/')
- word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
- word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
- word.tr!("-", "_")
- word.downcase!
- word
- end
+ protected
- # @!scope class
- def self.fetch(id)
- return unless identity_map
- attributes = identity_map.get("#{self.base_name}_#{id}")
- unless attributes
- result = Yammer.send("get_#{self.base_name}", id)
- attributes = result.body || {}
- unless attributes.empty?
- identity_map.put("#{self.base_name}_#{id}", attributes)
+ def attr_accessor_deffered(*symbols)
+ symbols.each do |key|
+ # track attributes the trigger fetch
+ fetchable_attrs[key] = false
+
+ # getter
+ define_method(key.to_s) do
+ load_deferred_attribute!(key)
+ instance_variable_get("@#{key}")
+ end
+
+ # setter
+ define_method("#{key}=") do |value|
+ load_deferred_attribute!(key)
+ if persisted? && loaded?
+ @modified_attributes[key] = value
+ else
+ @attrs[key] = value
+ end
+ instance_variable_set("@#{key}", value)
+ end
end
end
- attributes
end
- # @!scope class
- def self.get(id)
- new(fetch(id))
- end
-
attr_reader :id, :attrs
def initialize(props={})
@modified_attributes = {}
- @attrs = {}
- @new_record = true
- self.id = props.delete(:id)
- self.update(props)
+ @new_record = true
+ @loaded = false
+ @attrs = props
+ self.id = @attrs.delete(:id)
+ self.update(@attrs)
end
def base_name
self.class.base_name
end
def new_record?
@new_record
end
+ def persisted?
+ !new_record?
+ end
+
def changes
@modified_attributes
end
def modified?
!changes.empty?
end
+ def loaded?
+ @loaded
+ end
+
def load!
- result = self.class.fetch(@id)
- update(result)
+ @attrs = self.class.fetch(@id)
+ @loaded = true
+ update(@attrs)
+ self
end
- alias_method :reload!, :load!
+ def reload!
+ reset!
+ load!
+ end
+
def save
- return self if ((!new_record? && @modified_attributes.empty?) || @attrs.empty?)
+ return self if ((persisted? && @modified_attributes.empty?) || @attrs.empty?)
+
result = if new_record?
- Yammer.send("create_#{self.base_name}", @attrs)
+ Yammer.send("create_#{base_name}", @attrs)
else
- Yammer.send("update_#{self.base_name}", @id, @modified_attributes)
+ Yammer.send("update_#{base_name}", @id, @modified_attributes)
end
@modified_attributes = {}
self
end
def delete!
return if new_record?
- result = Yammer.send("delete_#{self.base_name}", @id)
+ result = Yammer.send("delete_#{base_name}", @id)
result.success?
end
private
@@ -119,13 +150,37 @@
return if model_id.nil?
@id = model_id.to_i
@new_record = false
end
+ # clear the entire class
+ def reset!
+ @modified_attributes = {}
+ @attrs = {}
+ @new_record = true
+ @loaded = false
+ end
+
protected
- def update(props={})
- props.each do |key, value|
+ # loads model
+ def load_deferred_attribute!(key)
+ if @attrs.empty? && persisted? && !loaded?
+ load!
+ if !@attrs.has_key?(key)
+ raise "The key: #{key} appears not to be supported for model: #{self.base_name} \n #{@attrs.keys.inspect}"
+ end
+ end
+ end
+
+ # set all fetchable attributes
+ def update(attrs={})
+ attrs.each do |key, value|
send("#{key}=", value)
+ end
+ if persisted? && !loaded?
+ @loaded = self.class.fetchable_attrs.keys.inject(true) do |result, key|
+ result && @attrs.has_key?(key)
+ end
end
end
end
end
\ No newline at end of file