module Couchbase::Model::Relationship::Parent::ClassMethods
Public Instance Methods
child(name, options = {})
click to toggle source
# File lib/couchbase/model/relationship/parent.rb, line 102 def child(name, options = {}) # TODO This may get the full module path for a relationship name, # and that will make the keys very long. Is this necessary? see: AR STI name = name.to_s.underscore unless name.is_a?(String) (@_children ||= []).push Relationship::Association.new(name, options) define_method("#{name}=") do |object| # FIXME Sanity check. If parent and parent != self, error object.parent = self if object.respond_to?(:parent) # Mark as loaded when we use the setter send("#{name}_loaded!") instance_variable_set :"@_child_#{name}", object end define_method("#{name}_loaded?") do instance_variable_get("@_child_#{name}_loaded") end define_method("#{name}_loaded!") do instance_variable_set("@_child_#{name}_loaded", true) end protected "#{name}_loaded!".to_sym define_method("#{name}") do # DO NOT USE Association#fetch IN THIS METHOD base_var_name = "@_child_#{name}" if (existing = instance_variable_get(base_var_name)).present? existing else if send("#{name}_loaded?") send("build_#{name}") else assoc = self.class.child_association_for(name) send("#{name}_loaded!") if (unloaded = assoc.load(self)).present? send("#{name}=", unloaded) end send(name) end end end define_method("build_#{name}") do |attributes = {}| assoc = self.class.child_association_for(name) send("#{name}=", assoc.child_class.new(attributes)).tap do |child| child.parent = self end end end
child_association_for(name)
click to toggle source
# File lib/couchbase/model/relationship/parent.rb, line 171 def child_association_for(name) @_children.detect {|association| association.name == name.to_s } end
child_association_names()
click to toggle source
# File lib/couchbase/model/relationship/parent.rb, line 163 def child_association_names children.map(&:name) end
child_associations()
click to toggle source
# File lib/couchbase/model/relationship/parent.rb, line 167 def child_associations @_children || [] end
children(*names)
click to toggle source
# File lib/couchbase/model/relationship/parent.rb, line 157 def children(*names) options = names.extract_options! names.each {|name| child name, options } end
find_all_with_children(ids, *children)
click to toggle source
FIXME This is a horrible abortion of a method
# File lib/couchbase/model/relationship/parent.rb, line 182 def find_all_with_children(ids, *children) ids = Array(ids) effective_children = if children.blank? @_children.select {|child| child.auto_load } else children = children.map(&:to_s) @_children.select {|child| children.include?(child.name) } end search_ids = ids.dup ids.each do |id| search_ids.concat(effective_children.map do |child| child.child_class.prefixed_id(id) end) end results = bucket.get(search_ids, quiet: true, extended: true) parent_objects = ids.map do |id| if results.key?(id) raw_new(id, results.delete(id)) else raise Couchbase::Error::NotFound.new("failed to get value (key=\"#{id}\"") end end parent_objects.each do |parent| results.each do |child_id, child_attributes| if unprefixed_id(parent.id) == unprefixed_id(child_id) assoc = effective_children.detect {|assoc| assoc.prefix == prefix_from_id(child_id) } parent.send "#{assoc.name}=", assoc.child_class.raw_new(child_id, child_attributes) end end effective_children.each {|assoc| parent.send("#{assoc.name}_loaded!") } end end
find_with_children(id, *children)
click to toggle source
# File lib/couchbase/model/relationship/parent.rb, line 175 def find_with_children(id, *children) return nil if id.blank? find_all_with_children(id, *children).first end
inherited(base)
click to toggle source
# File lib/couchbase/model/relationship/parent.rb, line 95 def inherited(base) children = child_associations base.class_eval do @_children = children.dup end end
raw_new(id, results)
click to toggle source
# File lib/couchbase/model/relationship/parent.rb, line 222 def raw_new(id, results) obj, flags, cas = results if obj.is_a?(Hash) obj.merge!(:_ignore_dirty => true) else obj = {:raw => obj} end new({:id => id, :meta => {'flags' => flags, 'cas' => cas}}.merge(obj)) end