module NCore module Associations def has_many(assoc, klass=nil) assoc = assoc.to_s klass ||= "#{module_name}::#{assoc.camelize.singularize}" key = "#{attrib_name}_id" class_eval <<-M1, __FILE__, __LINE__+1 def #{assoc}(params={}) return [] unless id reload = params.delete :reload if params.empty? # only cache unfiltered, default api call @attribs[:#{assoc}] = (!reload && @attribs[:#{assoc}]) || #{klass}.all({#{key}: id}, api_creds) else #{klass}.all(params.merge(#{key}: id), api_creds) end end M1 class_eval <<-M2, __FILE__, __LINE__+1 def find_#{assoc.singularize}(aid, params={}) raise UnsavedObjectError unless id #{klass}.find(aid, {#{key}: id}.reverse_merge(params), api_creds) end M2 # will always return the object; check .errors? or .valid? to see how it went class_eval <<-M3, __FILE__, __LINE__+1 def create_#{assoc.singularize}(params={}) raise UnsavedObjectError unless id #{klass}.create(params.merge(#{key}: id), api_creds) end M3 # will always return the object; check .errors? or .valid? to see how it went class_eval <<-M4, __FILE__, __LINE__+1 def update_#{assoc.singularize}(aid, params={}) obj = find_#{assoc.singularize}(aid) obj.update(params) obj # raise UnsavedObjectError unless id # #{klass}.update(aid, {#{key}: id}.reverse_merge(params), api_creds) end M4 class_eval <<-M5, __FILE__, __LINE__+1 def create_#{assoc.singularize}!(params={}) raise UnsavedObjectError unless id #{klass}.create!(params.merge(#{key}: id), api_creds) end M5 class_eval <<-M6, __FILE__, __LINE__+1 def update_#{assoc.singularize}!(aid, params={}) obj = find_#{assoc.singularize}(aid) obj.save!(params) end M6 # will always return the object; check .errors? or .valid? to see how it went class_eval <<-M7, __FILE__, __LINE__+1 def delete_#{assoc.singularize}(aid, params={}) obj = find_#{assoc.singularize}(aid) obj.delete(params) obj # raise UnsavedObjectError unless id # #{klass}.delete(aid, {#{key}: id}.reverse_merge(params), api_creds) end M7 class_eval <<-M8, __FILE__, __LINE__+1 def delete_#{assoc.singularize}!(aid, params={}) raise UnsavedObjectError unless id #{klass}.delete!(aid, {#{key}: id}.reverse_merge(params), api_creds) end M8 end # def embeds_many(assoc) # assoc = assoc.to_s # class_eval <<-M1, __FILE__, __LINE__+1 # def #{assoc}(params={}) # @attribs[:#{assoc}] ||= [] # end # M1 # class_eval <<-M2, __FILE__, __LINE__+1 # def find_#{assoc.singularize}(aid) # #{assoc}.detect{|o| o.id == aid} || raise(RecordNotFound) # end # M2 # # # appease activerecord: # class_eval <<-M3, __FILE__, __LINE__+1 # def #{assoc}_attributes=(v) # v = v.values if v.is_a?(Hash) # if v.is_a?(Array) # v.each{|o| o['object'] ||= '#{assoc.singularize}' if o.is_a?(Hash) } # @attribs[:#{assoc}] = self.class.interpret_type(v, api_creds) # else # @attribs[:#{assoc}] = v # end # end # alias :#{assoc}= :#{assoc}_attributes= # M3 # end def belongs_to(assoc, klass=nil) assoc = assoc.to_s klass ||= "#{module_name}::#{assoc.camelize}" class_eval <<-M1, __FILE__, __LINE__+1 attr :#{assoc}_id def #{assoc}(params={}) return nil unless #{assoc}_id # @attribs[:#{assoc}] ||= #{klass}.find(#{assoc}_id, params, api_creds) if params.empty? # only cache unfiltered, default api call @attribs[:#{assoc}] ||= #{klass}.find(#{assoc}_id, {}, api_creds) else #{klass}.find(#{assoc}_id, params, api_creds) end end M1 class_eval <<-M2, __FILE__, __LINE__+1 def #{assoc}_id=(v) @attribs[:#{assoc}] = nil unless @attribs[:#{assoc}_id] == v @attribs[:#{assoc}_id] = v end M2 end end end