我正在为Rails应用程序(Rails 4.2)中的有向图建模。模型对象包括Vertex
和Edge
。
vertex
可以是许多edges
的一部分 - 因此我们有以下关系:
vertex -- has_many --> edges
在两个顶点之间定义边 - 原点和终点。因此,我们定义了边与顶点的两个关联。
edge -- belongs_to --> :origin, class_name: 'Vertex'
edge -- belongs_to --> :terminus, class_name: 'Vertex'
我还限制删除属于某个边缘的顶点。这确保我不能删除作为图形一部分的顶点,除非它是浮动顶点。
但是如果我尝试删除浮动顶点(一个是图形的一部分但不是任何边缘的一部分),我仍然会收到错误:
ActiveRecord::StatementInvalid (Mysql::Error: Unknown column 'edges.vertex_id' in 'where clause': SELECT 1 AS one FROM edges WHERE edges.vertex_id = ? LIMIT 1)
现在边缘表明显没有vertex_id,只有origin_id
和terminus_id
。我该如何解决这个问题?
答案 0 :(得分:2)
我建议您指定foreign_key
选项:
指定用于关联的外键。 默认情况下是这样 猜测是具有“_id”后缀的关联的名称。那么一个 定义belongs_to:person关联的类将使用 “person_id”作为默认值:foreign_key。同样,belongs_to :favorite_person,class_name:" Person"将使用的外键 “favorite_person_id”。
belongs_to :origin, class_name: 'Vertex', foreign_key: 'origin_id'
belongs_to :terminus, class_name: 'Vertex', foreign_key: 'terminus_id'
答案 1 :(得分:0)
根据Зелёный建议的更改,模型看起来像这样:
class Vertex < ActiveRecord::Base
has_many :edges, dependent: :restrict_with_error
end
class Edge < ActiveRecord::Base
belongs_to :origin, class_name 'Vertex', foreign_key: 'origin_id'
belongs_to :terminus, class_name 'Vertex', foreign_key: 'terminus_id'
end
这仍然没有干净地删除依赖记录,但有足够的线索。我认为由于edges
的{{1}}成员显然存在歧义。目前尚不清楚这些边缘中的哪一个是当前顶点扮演起源角色,哪个是终点?
更自然的模式有助于解决这个问题。我没有使用Vertex
个引用,而是将其拆分为两个 - edges
和incoming_edges
,并为每个引用指定了外键。
outgoing_edges
这有助于解决删除问题。
注意:如果顶点是一个或多个边的一部分,则无法删除顶点:因此class Vertex < ActiveRecord::Base
has_many :incoming_edges, class_name: 'Edge', foreign_key: :terminus_id, dependent: :restrict_with_error
has_many :outgoing_edges, class_name: 'Edge', foreign_key: :origin_id, dependent: :restrict_with_error
end
子句。打扰顶点和边是restrict_with_error
对象的一部分。删除Graph
时,会删除边缘,然后删除边缘后断开的顶点。