module Yammer class Base 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}") end define_method ("#{key}=") do |value| if @attrs.fetch(key, false) && !new_record? @modified_attributes[key] = value else @attrs[key] = value end instance_variable_set("@#{key}", value) end end end # @!scope class def self.fetchable_keys @fetchable_keys ||= {} return @fetchable_keys end # @!scope class def self.identity_map @identity_map ||= Yammer::IdentityMap.new 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 # @!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) 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) end def base_name self.class.base_name end def new_record? @new_record end def changes @modified_attributes end def modified? !changes.empty? end def load! result = self.class.fetch(@id) update(result) end alias_method :reload!, :load! def save return self if ((!new_record? && @modified_attributes.empty?) || @attrs.empty?) result = if new_record? Yammer.send("create_#{self.base_name}", @attrs) else Yammer.send("update_#{self.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.success? end private def id=(model_id) return if model_id.nil? @id = model_id.to_i @new_record = false end protected def update(props={}) props.each do |key, value| send("#{key}=", value) end end end end