lib/hungry/resource.rb in hungry-0.0.1 vs lib/hungry/resource.rb in hungry-0.1.0

- old
+ new

@@ -1,38 +1,75 @@ -require 'httparty' +require 'httparty' unless defined? HTTParty module Hungry class Resource include HTTParty - attr_accessor :attributes + attr_accessor :attributes, :resources, :data_source ### CLASS METHODS: def self.get(*args) - puts "[Resource]: GET #{args.map(&:inspect).join(', ')}" self.base_uri Hungry.api_url super end - def self.belongs_to(resource, klass = Resource) + def self.belongs_to(resource, klass = 'Resource') define_method resource do - if url = resources[resource] - attributes = self.class.get url - klass.new(attributes) + @belongs_to ||= {} + @belongs_to[resource] ||= begin + klass = Kernel.const_get(klass) if klass.is_a?(String) + + if attributes[resource].present? + resource = klass.new attributes[resource] + resource.data_source = data_source + resource + elsif url = resources[resource] + attributes = self.class.get url + resource = klass.new attributes + resource.data_source = url + resource + end end end end - def self.has_many(resource, klass = Resource) + def self.has_many(resource, klass = 'Resource') define_method resource do - if url = resources[resource] - klass.collection.from_url(url) + @has_many ||= {} + @has_many[resource] ||= begin + klass = Kernel.const_get(klass) if klass.is_a?(String) + + if url = resources[resource] + collection = klass.collection.from_url(url) + + if attributes[resource].present? + collection.results = attributes[resource] + end + + collection + end end end end + def self.lazy_load(*attributes) + attributes.each do |attribute| + alias_method "#{attribute}_without_lazy_load".to_sym, attribute + define_method attribute do + result = send "#{attribute}_without_lazy_load".to_sym + + if !result.present? && (canonical_data_source != data_source && canonical_data_source.present?) + reload + send "#{attribute}_without_lazy_load".to_sym + else + result + end + end + end + end + class << self include Enumerable attr_writer :endpoint attr_writer :default_criteria @@ -54,17 +91,27 @@ end def find(id) raise NoEndpointSpecified unless endpoint - response = get "#{endpoint}/#{id}" + uri = "#{endpoint}/#{id}" + Util.log "GET: #{uri}" + response = get uri + if response.code == 200 - new(response) + attributes = Util.parse_json(response.body) + resource = new(attributes) + resource.data_source = uri + resource end end + def first(n = 1) + collection.first(n) + end + def all(criteria = {}) collection.all(criteria) end def each(&block) @@ -86,8 +133,29 @@ if respond_to?("#{key}=") send("#{key}=", value) end end + end + + def canonical_data_source + resources && resources[:self] + end + + def reload + resource = self.class.find id + + if resource + self.data_source = resource.data_source + initialize resource.attributes + else + self.data_source = nil + initialize Hash[*attributes.keys.map { |key| [key, nil] }] + end + + @has_many = {} + @belongs_to = {} + + self end end end