如何创建和保存一个引用自身的 Active Record 实例?

How do you create and save an Active Record instance that has a reference to itself?

Files 是一个 Active Record 模型,它引用了相同类型的父对象:

class Files < ActiveRecord::Base
  belongs_to :parent, class_name: "Files"
end

我想创建一个 root 条目,它的父级是它自己(它模仿根目录 .. 指向它自己)。

我尝试了几种不同的方法,其中大部分最终都试图将记录保存到数据库中,而父项仍设置为空。如果该字段为空,则数据库设置为抛出异常。我试过:

Files.new { |f|
  f.parent   = f
}.save

Files.create { |f|
  f.parent   = f
}

我也试过了

Files.new { |f|
  f.parent_id = f.id = Files.next_sequence_value
}.save

而且我看过 build_parent

创建 self-referential 关联时,外键列必须可为空且关联必须是可选的。否则,您将陷入先有鸡还是先有蛋的局面,您无法创建第一条记录,因为它必须引用不存在的记录。

class Files < ActiveRecord::Base
  belongs_to :parent, 
    class_name: self.name,
    optional: true
end

使用下一个序列值实际上不是一个好的选择,因为如果您有外键约束,它将不起作用。

这里的命名也是有问题的。 Files 是复数形式,这将打破惯例并导致各种问题,同时还会绊倒您的开发人员。但是 File 将不起作用,因为它是 Ruby StdLib 的一部分。我建议使用附件、文档等替代方法,或使用 MyApp::File.

等命名空间