我正在尝试在 Rails 3 中构建文本冒险游戏(是的,我知道这很愚蠢)。现在我有一个模型叫做 Room。每个房间需要与最多四个其他房间相关联。这种关系是双向的,因此任何两个相关的房间都是彼此的出口。例如,如果我要说:
@room1.north = @room2
@room2.south 会自动变成@room1。同样,如果我说:
@room1.east = nil
@room2.west 也变为 nil。我想只使用模型关联来实现这一点,而不是在控制器中手动完成。这可能吗?
编辑
matzi 给出的第一个例子并不能完全按照我想要的方式工作。考虑以下:
class Room < ActiveRecord::Base
attr_accessible :north, :south, :east, :west
has_one :north, :class_name => "Room", :foreign_key => "south_id"
has_one :east, :class_name => "Room", :foreign_key => "west_id"
belongs_to :south, :class_name => "Room", :foreign_key => "south_id"
belongs_to :west, :class_name => "Room", :foreign_key => "west_id"
end
@room1 = Room.new
@room2 = Room.new
@room1.save
@room2.save
这工作正常:
@room1.north = @room2
@room1.north #Outputs @room2
@room2.south #Outputs @room1
@room1.north = nil
@room1.north #Outputs nil
@room2.south #Outputs nil
到现在为止还挺好。但:
@room1.north = @room2
@room2.south = nil
@room1.north #Outputs @room2, but it should be nil
@room2.south #Outputs nil
此外:
@room2.south = @room1
@room1.north #Outputs nil, but it should be @room2
@room2.south #Outputs @room1
看到这里的问题了吗?这并不是真正的双向。
解决了
事实证明,Matzi 的第一个解决方案毕竟是正确的。正如他所指出的,我在使用该解决方案时遇到的问题是储蓄问题。以下作品:
@room1 = Room.create
@room2 = Room.create
@room1.north = @room2
@room1.save
Room.find(1).north #Room 2
Room.find(2).south #Room 1
@room2.south = nil
@room2.save
Room.find(1).north #nil
Room.find(2).south #nil