Neo4j.rb如何将ActiveRel关系子类化?

时间:2017-09-07 13:39:18

标签: ruby-on-rails ruby neo4j neo4j.rb

Newbie Neo4j.rb(v8.2.1)gem用户在这里试图找出如何正确处理ActiveRel的子类...

我有一个名为HasAccount的关系类型,然后我在其他类型中继承,即OwnsAccount < HasAccount。我在我的模型中定义了这样的关系:

has_many :out, :accounts, rel_class: :HasAccount
has_many :out, :owned_accounts, rel_class: :OwnsAccount
has_many :out, :managed_accounts, rel_class: :ManagesAccount

我的意图是,每当我为一个节点创建OwnsAccountManagesAccount关系时,他们也可以通过my_node.accounts访问(即超类&#39; {{ 1}})。

我接近这个错误吗?我已经尝试过各种方式而且完全放弃了has_many并且定义了合并HasAccountaccounts的{​​{1}}方法...

2 个答案:

答案 0 :(得分:1)

Adam Sharp @adamsharp Sep 07 13:32 @cheerfulstoic - 毫不拖延! &lt; 24小时免费产品是闪电服务!感觉更好,知道答案不是“这就是你犯下的愚蠢错误。”#34;谢谢。 是的,我原本希望ActiveRel上的继承与ActiveNode上的继承一样,其中子类项是每个级别的.all的一部分。我在我的项目中有一些实例,我可以直接进行,但有一两个地方我需要关系中的其他属性和逻辑。

我还考虑了另外两种方法:

1)只拥有HasAccount但具有角色属性。但我无法找出为父节点编写owns方法的最简单方法,如下所示:

def owns
  self.accounts.(SOME LOGIC FOR role == 'owner' IN THE REL)
end

还不确定如何在设置后更改角色,并想知道性能方面的单独rels是否会更好。

2)将所有逻辑重构为中间ActiveNode类型,即本例中的AccountRole,我可以将其子类化为OwnerRole&lt; AccountRole节点将包含在任一范围内。然后我的模型的关键位是:

class AccountRole
  include Neo4j::ActiveRel

  from_class :User
  to_class   :Account

  def account
    self.to_node
  end
end

class OwnerRole < AccountRole

end

class User

  include Neo4j::ActiveNode
  include Neo4j::Timestamps

  has_many :out, :has_account_roles, rel_class: :AccountRole
  has_many :out, :has_owner_roles, rel_class: :OwnerRole

  def accounts
    self.has_account_roles.map{ |role| role.account }
  end

  def owns
    self. has_owner_role.map{ |role| role.account }
  end

end

现在倾向于#2,但非常热衷于你的选择。

再次感谢!

Brian Underwood @cheerfulstoic Sep 07 20:29 @adamsharp实际上,用self.accounts.rel_where(角色:'所有者)做#1应该很容易 然后,owns方法仍将返回表示Account节点的QueryProxy,您可以进一步过滤或链接关联。你也可以在User上实现一个具有相同名称的类方法(如self.accounts.rel_where(role:'owner)),它允许你链接User.all.owns或Something.users.owns等...

Adam Sharp @adamsharp Sep 07 21:44 真棒。谢谢@cheerfulstoic!会试一试。改变房产的最简单方法是什么? (即从老板到经理)?

Brian Underwood @cheerfulstoic Sep 07 21:57 如果你有一个ActiveRel对象,你可以说rel.role ='owner'; rel.save / rel.update(角色:'所有者')。否则你会使用Cypher或Ruby API,例如user.owns(:node,:rel).where(id:account.id).query.set(rel:{role:'owner'})。exec(显然更多详细,但如果您要更新多个语法,则该语法非常有用)

Adam Sharp @adamsharp 13:48 谢谢@cheerfulstoic。是的,它试图构建后者,并且通常会找到干净的方式来访问相关对象,这些对象将我绑在那个方面。会走这条路。谢谢您的帮助!我的整个职业生涯都是一个SQL人。这很好玩。

答案 1 :(得分:0)

我不认为子类ActiveRel类会有所帮助,不幸的是(可能你已经发现了;)。)

如果您没有ActiveRel课程,则可以指定多种类型(我不记得是否实施了type: [:OWNS_ACCOUNT, :MANAGES_ACCOUNT],但您当然可以执行type: "OWNS_ACCOUNT|MANAGES_ACCOUNT”’或{{1 } / type: false)。

如果你需要对你的人际关系有逻辑,那么你需要type: :any。我认为你可以在ActiveRel课程上type :any,但我不知道你在这种情况下如何分别有ActiveRel / owned_accounts个关联(我认为{ {1}}和managed_accounts是相互排斥的,但可能会尝试工作)。

真的,我们应该考虑type,我认为