Rails 4 has_one 自参考专栏

Rails 4 has_one self reference column

我有图腾模型和图腾table。

会有很多图腾,我需要将图腾的顺序存储在数据库中table。 我在图腾 table 中添加了 previous_totem_id 和 next_totem_id 来存储订单信息。我通过这个做到了 Rails 迁移:

class AddPreviousNextTotemColumnsToTotems < ActiveRecord::Migration
  def change
    add_column :totems, :previous_totem_id, :integer
    add_column :totems, :next_totem_id, :integer
  end
end

现在我在模型中定义了关系:

class Totem < ActiveRecord::Base
  validates :name, :presence => true

  has_one :previous_totem, :class_name => 'Totem'
  has_one :next_totem, :class_name => 'Totem'
end

我通过 ActiveRecord 创建了几个这样的图腾,并尝试像这样使用 previous_totem_id 列:

totem = Totem.create! name: 'a1'
Totem.create! name: '1a'
totem.previous_totem_id = Totem.find_by(name: '1a').id
puts totem.previous_totem #This is NIL

但是,previous_totem 返回为 nil,调用此行

时,我在 mysql 日志中没有看到 select 语句
totem.previous_totem

这段关系值得推荐吗?实现自引用列的最佳方法是什么?

如果自引用的唯一原因是存储图腾的顺序,请不要这样做。今天是你的幸运日:这是一个已解决的问题!

使用 position 字段和 acts_as_list gem,这将以简洁高效的方式为您解决这个问题。

将关联的方向从 has_one 更改为 belongs_to 并指定外键,应该会使您的代码按预期工作:

class Totem < ActiveRecord::Base
  validates :name, :presence => true

  belongs_to :previous_totem, :class_name => 'Totem', foreign_key: :previous_totem_id
  belongs_to :next_totem, :class_name => 'Totem', foreign_key: :next_totem_id
end

但是,好的关联应该在双方都正确命名和声明 - 匹配 has_one 关联;在这种情况下,没有命名冲突是不可能的:) Self join 有时可能有用,但我不确定这是否是这里的最佳解决方案。我没有使用 gem moveson 推荐的方法,但是我使用了一个整数列来存储位置,恕我直言,这使得重新排序记录更容易:)