我试图覆盖一个声明关系的setter方法,以在旧节点和新节点上执行自定义行为和一些验证。
举个例子:
class FantasticTeam
include Neo4j::ActiveNode
has_one :in, :active, model_class: Whatever
has_many :in, :not_active, model_class: Whatever
def active=(whatever)
# return if whatever is not include in :not_active
# add the old value to :not_active
# delete the relationship :not_active that belongs to whatever (the param)
# add :active relationship to whatever
end
end
做这种事的正确方法是什么?
有两种方法可以处理这一问题,都比重写setter方法更容易。
第一种是在ActiveNode模型中使用回调。
class FantasticTeam
include Neo4j::ActiveNode
has_one :in, :active, before: :before_callback, model_class: Whatever
has_many :in, :not_active, model_class: Whatever
private
def before_callback(other)
return false unless self.not_active.include?(other)
self.not_active(:w, :r).where(uuid: other.uuid).pluck(:r).each { |r| r.destroy }
self.not_active << other unless self.active.nil?
end
end
我个人从来没有使用过这个过程。对于任何关系逻辑,我总是使用ActiveRel模型。
class FantasticTeam
include Neo4j::ActiveNode
has_one :in, :active, model_class: 'Whatever', rel_class: 'FantasticActiveWhatever'
has_many :in, :not_active, model_class: 'Whatever'
end
class FantasticActiveWhatever
include Neo4j::ActiveRel
from_class FantasticTeam
to_class Whatever
type 'ACTIVE'
validate :inactive
before_create :clear_inactive
private
def inactive
self.errors.add(:inactive, 'Destination node must be declared inactive') unless from_node.not_active.include?(to_node)
end
def clear_inactive
from_node.not_active(:w, :r).where(uuid: to_node.uuid).pluck(:r).each { |r| r.destroy }
end
end
然后你会创建:
rel=FantasticActiveWhatever.new(从_node:团队,到_node:随便)如果rel.save#继续结束
ActiveRel需要一些额外的设置,但它的功能要强大得多。
无论哪种方式,这都需要封装在事务中,因为存在删除not_active
关系但无法设置active
的可能性。
begin
tx = Neo4j::Transaction.new
# the whole process
rescue StandardError
tx.failure
# additional failure behavior, if any
ensure
tx.close
end
基本关系回调记录在https://github.com/neo4jrb/neo4j/wiki/Neo4j-v3-Declared-Relationships#relationship-回调。
ActiveRel在https://github.com/neo4jrb/neo4j/wiki/Neo4j%3A%3AActiveRel.
交易记录在https://github.com/neo4jrb/neo4j/wiki/Transaction.