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