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