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 推荐的方法,但是我使用了一个整数列来存储位置,恕我直言,这使得重新排序记录更容易:)
我有图腾模型和图腾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 推荐的方法,但是我使用了一个整数列来存储位置,恕我直言,这使得重新排序记录更容易:)