我将给出一个快速背景。我正在使用以下(汇总)模型在Rails中构建有向图:
Node
has_many :edges, foreign_key: "source_id"
和
Edge
field :source_id, :type => String
field :destination_id, :type => String
belongs_to :source, class_name: "Node"
belongs_to :destination, class_name: "Node"
我遇到过Mongoid has_many和belongs_to关系的两个奇怪问题。关系查询的结果似乎取决于我用来检索Node
对象的方法。
首先,在关系上调用to_a
(以及枚举关系,即each
,map
,collect
)会导致要检索的额外Edge
,如下所示,计数返回为31。
第二次,只有当检索Edge
的查询与直接Node
不同时,才会出现额外find
的问题。但正如您所看到的,根据Rails node1
等于node2
。
如果有人能对这些问题有所了解,我将不胜感激。如果有其他信息可以帮助我,请告诉我。
1.9.3-p327 :145 > node1 = some_other_node.neighbors.select {|n| n[:node].city == "983"}.first[:node]
=> #<Node _id: 54da32b1756275343ed70300, city: "983">
1.9.3-p327 :140 > node2 = Node.find_by(:city => "983")
=> #<Node _id: 54da32b1756275343ed70300, city: "983">
1.9.3-p327 :141 > node1 == node2
=> true
1.9.3-p327 :150 > node1.edges.count
=> 30
1.9.3-p327 :151 > node1.edges.to_a.count
=> 31
1.9.3-p327 :152 > node2.edges.count
=> 30
1.9.3-p327 :153 > node2.edges.to_a.count
=> 30
编辑提供有关额外优势的信息。
返回的额外Edge
应返回绝对不。您可以在下面看到额外的Edge
source
与node1
不等于。返回的每个其他Edge
都有node1
作为来源,这正是我根据关系所期望的。
1.9.3-p327 :167 > node1.edges.to_a.last.source
=> #<Node _id: 54da32b0756275343e000000, city: "0">
以下是支持我的主张的更多证据。请注意,所有node2
边都有node2
作为source
,但node1
不适用。
1.9.3-p327 :170 > node2.edges.to_a.collect {|e| e.source == node2}.include? false
=> false
1.9.3-p327 :171 > node1.edges.to_a.collect {|e| e.source == node1}.include? false
=> true
但是,额外的Edge
将city: "0"
作为来源是很奇怪的,因为在node1
的初始分配中some_other_node
是city: "0"
。这似乎不是巧合。
答案 0 :(得分:1)
问题解决了!谢谢你的建议mu太短了。当我试图在out_edges
上实现in_edges
和Node
时,我发现Mongoid抱怨反向关系模棱两可。有趣的是,当我只定义out_edges
时,它很高兴。
只是为了澄清,定义out_edges
和in_edges
需要不,我能够通过包含inverse_of
来消除缺陷Edge
模型中的定义。
Node
has_many :edges, foreign_key: "source_id"
Edge
field :source_id, :type => String
field :destination_id, :type => String
belongs_to :source, inverse_of: "edges", class_name: "Node"
belongs_to :destination, inverse_of: "in_edges", class_name: "Node"
修改
Rails / Mongoid似乎并不关心destination
是否使用inverse_of: "in_edges"
定义,即使Node中不存在in_edges
。但是,如果我删除该部分,则问题将返回。 Mongoid肯定有一些缺陷。