Neo4j.rb 如何继承 ActiveRel 关系?
Neo4j.rb How to Subclass ActiveRel relationship?
新手 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
我的意图是,每当我为节点创建 OwnsAccount
或 ManagesAccount
关系时,它们也可以通过 my_node.accounts
访问(即超类 has_many
).
我是不是处理错了?我已经尝试了每一种方式,并且避免完全放弃 HasAccount
并定义一个合并 owned_accounts
和 managed_accounts
...
的 accounts
方法
不幸的是,我不认为 subclasses ActiveRel
classes 会有帮助(可能你已经发现了 ;))。
如果你没有 ActiveRel
class 你可以指定多种类型(我不记得我们是否实现了 type: [:OWNS_ACCOUNT, :MANAGES_ACCOUNT]
但你当然可以做任何一个 type: "OWNS_ACCOUNT|MANAGES_ACCOUNT”’
或 type: false
/ type: :any
).
如果你需要对你的关系有逻辑,那么你需要 ActiveRel
。我想你可以在 ActiveRel
class 上有 type :any
,但我不知道在那种情况下你如何拥有单独的 owned_accounts
/ managed_accounts
关联(我认为 type
和 rel_class
是互斥的,但它可能是工作尝试)。
真的,也许,我们应该考虑 rel_class: [:OwnsAccount, :ManagesAccount]
,我认为
Adam Sharp @adamsharp 9 月 7 日 13:32
@cheerfulstoic — 一点都不拖延! <24小时免费产品闪电服务!知道答案不是 "here's the stupid mistake you made." 也感觉好多了,谢谢。
是的,我曾希望 ActiveRel
上的继承会像 ActiveNode
上的那样,其中 subclassed 项目是每个级别的 .all 的一部分。我在我的项目中有一些实例可以使用直接方法,但是在一两个地方我需要关系中的其他属性和逻辑。
我还考虑了另外两种方法:
1) 只有 HasAccount 但具有角色 属性。但是我很难找出为父节点编写 owns 方法的最简单方法,类似于:
def owns
self.accounts.(SOME LOGIC FOR role == 'owner' IN THE REL)
end
也不确定如何在设置后更改角色,并且想知道性能方面的单独 rels 是否会更好。
2) 将所有逻辑重构为中间 ActiveNode 类型,即本例中的 AccountRole ,我可以将其子class 以便 OwnerRole < 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 9 月 07 20:29
@adamsharp 实际上,用 self.accounts.rel_where(role: ‘owner) 之类的东西做 #1 应该很容易
然后 owns 方法仍然 return 一个 QueryProxy 表示您可以进一步过滤或链接关联的帐户节点。您还可以在 User 上使用相同名称的 class 方法实现所有(例如 self.accounts.rel_where(role: 'owner)),这将允许您像 User.all.owns 或 Something.users.owns, 等...
Adam Sharp @adamsharp 9 月 7 日 21:44
惊人的。谢谢@cheerfulstoic!会试一试。更改 rel 属性 最简单的方法是什么? (即从所有者到经理)?
Brian Underwood @cheerfulstoic 9 月 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(显然这更冗长,但如果您要更新多个,该语法会很有用)
亚当夏普@adamsharp 13:48
谢谢@cheerfulstoic。是的,它试图构建后者,并通常找出访问相关对象的简洁方法,这让我在这方面陷入了困境。会走这条路。谢谢您的帮助!我的整个职业生涯都是 SQL 人。这好有趣。
新手 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
我的意图是,每当我为节点创建 OwnsAccount
或 ManagesAccount
关系时,它们也可以通过 my_node.accounts
访问(即超类 has_many
).
我是不是处理错了?我已经尝试了每一种方式,并且避免完全放弃 HasAccount
并定义一个合并 owned_accounts
和 managed_accounts
...
accounts
方法
不幸的是,我不认为 subclasses ActiveRel
classes 会有帮助(可能你已经发现了 ;))。
如果你没有 ActiveRel
class 你可以指定多种类型(我不记得我们是否实现了 type: [:OWNS_ACCOUNT, :MANAGES_ACCOUNT]
但你当然可以做任何一个 type: "OWNS_ACCOUNT|MANAGES_ACCOUNT”’
或 type: false
/ type: :any
).
如果你需要对你的关系有逻辑,那么你需要 ActiveRel
。我想你可以在 ActiveRel
class 上有 type :any
,但我不知道在那种情况下你如何拥有单独的 owned_accounts
/ managed_accounts
关联(我认为 type
和 rel_class
是互斥的,但它可能是工作尝试)。
真的,也许,我们应该考虑 rel_class: [:OwnsAccount, :ManagesAccount]
,我认为
Adam Sharp @adamsharp 9 月 7 日 13:32
@cheerfulstoic — 一点都不拖延! <24小时免费产品闪电服务!知道答案不是 "here's the stupid mistake you made." 也感觉好多了,谢谢。
是的,我曾希望 ActiveRel
上的继承会像 ActiveNode
上的那样,其中 subclassed 项目是每个级别的 .all 的一部分。我在我的项目中有一些实例可以使用直接方法,但是在一两个地方我需要关系中的其他属性和逻辑。
我还考虑了另外两种方法:
1) 只有 HasAccount 但具有角色 属性。但是我很难找出为父节点编写 owns 方法的最简单方法,类似于:
def owns
self.accounts.(SOME LOGIC FOR role == 'owner' IN THE REL)
end
也不确定如何在设置后更改角色,并且想知道性能方面的单独 rels 是否会更好。
2) 将所有逻辑重构为中间 ActiveNode 类型,即本例中的 AccountRole ,我可以将其子class 以便 OwnerRole < 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 9 月 07 20:29 @adamsharp 实际上,用 self.accounts.rel_where(role: ‘owner) 之类的东西做 #1 应该很容易 然后 owns 方法仍然 return 一个 QueryProxy 表示您可以进一步过滤或链接关联的帐户节点。您还可以在 User 上使用相同名称的 class 方法实现所有(例如 self.accounts.rel_where(role: 'owner)),这将允许您像 User.all.owns 或 Something.users.owns, 等...
Adam Sharp @adamsharp 9 月 7 日 21:44 惊人的。谢谢@cheerfulstoic!会试一试。更改 rel 属性 最简单的方法是什么? (即从所有者到经理)?
Brian Underwood @cheerfulstoic 9 月 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(显然这更冗长,但如果您要更新多个,该语法会很有用)
亚当夏普@adamsharp 13:48 谢谢@cheerfulstoic。是的,它试图构建后者,并通常找出访问相关对象的简洁方法,这让我在这方面陷入了困境。会走这条路。谢谢您的帮助!我的整个职业生涯都是 SQL 人。这好有趣。