lib/restly/associations.rb in restly-0.0.1.alpha.1 vs lib/restly/associations.rb in restly-0.0.1.alpha.2
- old
+ new
@@ -8,34 +8,77 @@
autoload :HasManyThrough
autoload :HasOne
autoload :HasOneThrough
autoload :EmbeddableResources
- class AssociationHash < HashWithIndifferentAccess
+ class AssociationsSet < HashWithIndifferentAccess
end
+ class IndifferentSet < Set
+
+ def include?(attr)
+ return super unless attr.is_a?(Symbol) || attr.is_a?(String)
+ super(attr.to_s) || super(attr.to_sym)
+ end
+
+ end
+
included do
- extend EmbeddableResources if self == Restly::Base
+ include Restly::ConcernedInheritance
+ extend EmbeddableResources if self == Restly::Base
include Restly::NestedAttributes
delegate :resource_name, to: :klass
class_attribute :resource_associations, instance_reader: false, instance_writer: false
- self.resource_associations = AssociationHash.new
+ attr_reader :association_attributes
+
+ self.resource_associations = AssociationsSet.new
+
inherited do
self.resource_associations = resource_associations.dup
end
end
- def stub_associations_from_response(response=self.response)
- parsed = response.parsed || {}
- parsed = parsed[resource_name] if parsed.is_a?(Hash) && parsed[resource_name]
- associations = parsed.select{ |i| klass.reflect_on_all_resource_associations.keys.include?(i) }
- associations.each do |relationship|
- relationship.collection?
+ def associations
+ IndifferentSet.new klass.reflect_on_all_resource_associations.keys.map(&:to_sym)
+ end
+
+ def set_association(attr, val)
+ association = klass.reflect_on_resource_association(attr)
+ association.valid?(val)
+ @association_attributes[attr] = val
+ end
+
+ def get_association(attr, options={})
+ association = klass.reflect_on_resource_association(attr)
+ (@association_attributes ||= {}.with_indifferent_access)[attr] || set_association(attr, association.load(self, options))
+ end
+
+ def respond_to_association?(m)
+ !!(/(?<attr>\w+)(?<setter>=)?$/ =~ m.to_s) && associations.include?(attr.to_sym)
+ end
+
+ def respond_to?(m, include_private = false)
+ respond_to_association?(m) || super
+ end
+
+ private
+
+ def method_missing(m, *args, &block)
+ if !!(/(?<attr>\w+)(?<setter>=)?$/ =~ m.to_s) && associations.include?(m)
+ attr = attr.to_sym
+ case !!setter
+ when true
+ set_association(attr, *args)
+ when false
+ get_association(attr)
+ end
+ else
+ super(m, *args, &block)
end
end
def klass
self.class
@@ -45,45 +88,62 @@
def resource_name
name.gsub(/.*::/,'').underscore
end
+ def reflect_on_resource_association(association_name)
+ reflect_on_all_resource_associations[association_name]
+ end
+
def reflect_on_all_resource_associations
resource_associations
end
private
# Belongs to
def belongs_to_resource(name, options = {})
exclude_field(name) if ancestors.include?(Restly::Base)
self.resource_associations[name] = association = BelongsTo.new(self, name, options)
+
define_method name do |options={}|
- association.find_with_parent(self, options)
+ get_association(name, options)
end
+
+ define_method "#{name}=" do |value|
+ set_association name, value
+ end
+
end
# Has One
def has_one_resource(name, options = {})
exclude_field(name) if ancestors.include?(Restly::Base)
self.resource_associations[name] = association = HasOne.new(self, name, options)
+
define_method name do |options={}|
- association.scope_with_parent(self, options)
+ get_association(name, options)
end
+
+ define_method "#{name}=" do |value|
+ set_association name, value
+ end
+
end
# Has One
def has_many_resources(name, options = {})
exclude_field(name) if ancestors.include?(Restly::Base)
self.resource_associations[name] = association = HasMany.new(self, name, options)
+
define_method name do |options={}|
- association.scope_with_parent(self, options)
+ get_association(name, options)
end
- end
+ define_method "#{name}=" do |value|
+ set_association name, value
+ end
- def reflect_on_resource_association(association_name)
- reflect_on_all_resource_associations[association_name]
end
end
end
\ No newline at end of file