RoR:模型多次引用自身

时间:2016-02-09 20:34:26

标签: ruby-on-rails activerecord rails-activerecord self-referencing-table

我有一个房间模型。每个房间有6个出口(北,东,南,西,上,下),我应该能够做document.getElementById('mySelect').addEventListener('change', function() { window.location.href = this.value; }, false): 之类的事情,以便将房间带到第一个房间的北面。我制作的模型如下:

Room.first.nr

但是,在rails c中执行此操作

class Room < ApplicationRecord

  has_one :nr, class_name: 'Room', foreign_key: :id
  belongs_to :sr, class_name: 'Room'

  has_one :er, class_name: 'Room', foreign_key: :id
  belongs_to :wr, class_name: 'Room'

  has_one :sr, class_name: 'Room', foreign_key: :id
  belongs_to :nr, class_name: 'Room'

  has_one :wr, class_name: 'Room', foreign_key: :id
  belongs_to :er, class_name: 'Room'

  has_one :ur, class_name: 'Room', foreign_key: :id
  belongs_to :dr, class_name: 'Room'

  has_one :dr, class_name: 'Room', foreign_key: :id
  belongs_to :ur, class_name: 'Room'

end

我得到了这个:

Room.create!(title:'sometitle', description:'somedescription', er: Room.first)

我一直在玩ActiveRecord::RecordInvalid: Validation failed: Sr must exist, Wr must exist, Nr must exist, Dr must exist, Ur must exist 也无济于事。

这是我的迁移:

inverse_of

2 个答案:

答案 0 :(得分:1)

您的关联名称存在冲突(即has_one :nrbelongs_to :nr)。应该类似于以下内容:

class Room < ApplicationRecord

  belongs_to :sr, class_name: 'Room'
  belongs_to :wr, class_name: 'Room'
  belongs_to :nr, class_name: 'Room'
  belongs_to :er, class_name: 'Room'
  belongs_to :dr, class_name: 'Room'
  belongs_to :ur, class_name: 'Room'

end

我认为您仍然不需要has_one关系。因为您已经可以通过这些belongs_to

获得所有方向的房间

答案 1 :(得分:0)

好的,花了一段时间但我明白了。

该模型采用以下形式:

class Room < ApplicationRecord

  has_one :nr, class_name: 'Room', foreign_key: 'sr_id', inverse_of: :sr

  has_one :er, class_name: 'Room', foreign_key: 'wr_id', inverse_of: :wr

  has_one :sr, class_name: 'Room', foreign_key: 'nr_id', inverse_of: :nr

  has_one :wr, class_name: 'Room', foreign_key: 'er_id', inverse_of: :er

  has_one :ur, class_name: 'Room', foreign_key: 'dr_id', inverse_of: :dr

  has_one :dr, class_name: 'Room', foreign_key: 'ur_id', inverse_of: :ur

end

所以我可以做到

a=Room.create(title:'the title', description: 'the description')
a.er = Room.find(1)
a.save

这是正确的:

Room.find(1).wr == Room.last

非常感谢@ Jay-Ar Polidario