RoR:模型多次引用自身
RoR: Model referencing itself multiple times
我有一个房间模型。每个房间有 6 个出口(北、东、南、西、上、下),我应该可以做 Room.first.nr
之类的事情,让房间位于第一个房间的北边。我制作的模型如下:
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
但是,在 rails c
中执行此操作时
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
没用。
这是我的迁移:
class CreateRooms < ActiveRecord::Migration[5.0]
def change
create_table :rooms do |t|
t.string :title, null: false
t.text :description, null: false
t.integer :nr_id, null: true
t.integer :er_id, null: true
t.integer :sr_id, null: true
t.integer :wr_id, null: true
t.integer :ur_id, null: true
t.integer :dr_id, null: true
t.timestamps
end
add_index :rooms, :nr_id
add_index :rooms, :er_id
add_index :rooms, :sr_id
add_index :rooms, :wr_id
add_index :rooms, :ur_id
add_index :rooms, :dr_id
end
end
您的关联名称存在冲突(即 has_one :nr
和 belongs_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
四面八方的房间了
好吧,花了点时间,但我想通了。
模型采用这种形式:
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
我有一个房间模型。每个房间有 6 个出口(北、东、南、西、上、下),我应该可以做 Room.first.nr
之类的事情,让房间位于第一个房间的北边。我制作的模型如下:
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
但是,在 rails c
中执行此操作时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
没用。
这是我的迁移:
class CreateRooms < ActiveRecord::Migration[5.0]
def change
create_table :rooms do |t|
t.string :title, null: false
t.text :description, null: false
t.integer :nr_id, null: true
t.integer :er_id, null: true
t.integer :sr_id, null: true
t.integer :wr_id, null: true
t.integer :ur_id, null: true
t.integer :dr_id, null: true
t.timestamps
end
add_index :rooms, :nr_id
add_index :rooms, :er_id
add_index :rooms, :sr_id
add_index :rooms, :wr_id
add_index :rooms, :ur_id
add_index :rooms, :dr_id
end
end
您的关联名称存在冲突(即 has_one :nr
和 belongs_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
好吧,花了点时间,但我想通了。
模型采用这种形式:
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