lib/neo4j/active_rel/persistence.rb in neo4j-4.1.5 vs lib/neo4j/active_rel/persistence.rb in neo4j-5.0.0.rc.1

- old
+ new

@@ -5,11 +5,14 @@ class RelInvalidError < RuntimeError; end class ModelClassInvalidError < RuntimeError; end class RelCreateFailedError < RuntimeError; end - def clear_association_cache; end + # Should probably find a way to not need this + def association_proxy_cache + {} + end def save(*) update_magic_properties create_or_update end @@ -17,14 +20,14 @@ def save!(*args) fail RelInvalidError, self unless save(*args) end def create_model(*) - confirm_node_classes + validate_node_classes! create_magic_properties set_timestamps - properties = convert_properties_to :db, props + properties = self.class.declared_property_manager.convert_properties_to(self, :db, props) rel = _create_rel(from_node, to_node, properties) return self unless rel.respond_to?(:_persisted_obj) init_on_load(rel._persisted_obj, from_node, to_node, @rel_type) true end @@ -48,55 +51,40 @@ end end private - def confirm_node_classes + def validate_node_classes! [from_node, to_node].each do |node| type = from_node == node ? :_from_class : :_to_class - next if allows_any_class?(type) - fail ModelClassInvalidError, "Node class was #{node.class}, expected #{self.class.send(type)}" unless class_as_constant(type) == node.class || node.class.ancestors.include?(class_as_constant(type)) + type_class = self.class.send(type) + + next if [:any, false].include?(type_class) + + fail ModelClassInvalidError, "Node class was #{node.class}, expected #{type_class}" unless node.is_a?(type_class.to_s.constantize) end end def _create_rel(from_node, to_node, *args) props = self.class.default_property_values(self) props.merge!(args[0]) if args[0].is_a?(Hash) set_classname(props, true) - _rel_creation_query(from_node, to_node, props) - end - def class_as_constant(type) - given_class = self.class.send(type) - case given_class - when String - given_class.constantize - when Symbol - given_class.to_s.constantize - else - given_class + if from_node.id.nil? || to_node.id.nil? + fail RelCreateFailedError, "Unable to create relationship (id is nil). from_node: #{from_node}, to_node: #{to_node}" end + _rel_creation_query(from_node, to_node, props) end - def allows_any_class?(type) - self.class.send(type) == :any || self.class.send(type) == false - end - private + N1_N2_STRING = 'n1, n2' + ACTIVEREL_NODE_MATCH_STRING = 'ID(n1) = {n1_neo_id} AND ID(n2) = {n2_neo_id}' def _rel_creation_query(from_node, to_node, props) - from_class = from_node.class - to_class = to_node.class - begin - Neo4j::Session.query.match(n1: from_class.mapped_label_name, n2: to_class.mapped_label_name) - .where("n1.#{from_class.primary_key} = {from_node_id}") - .where("n2.#{to_class.primary_key} = {to_node_id}") - .params(from_node_id: from_node.id, to_node_id: to_node.id) - .send(create_method, ("(n1)-[r:`#{type}`]->(n2)")) - .with('r').set(r: props).return(:r).first.r - rescue NoMethodError => e - raise RelCreateFailedError, "Unable to create relationship. from_node: #{from_node}, to_node: #{to_node}, error: #{e}" - end + Neo4j::Session.query.match(N1_N2_STRING) + .where(ACTIVEREL_NODE_MATCH_STRING).params(n1_neo_id: from_node.neo_id, n2_neo_id: to_node.neo_id).break + .send(create_method, "n1-[r:`#{type}`]->n2") + .with('r').set(r: props).pluck(:r).first end def create_method self.class.unique? ? :create_unique : :create end