一对一的DataMapper关联
我是DataMapper的新手,我正在尝试为以下场景创建模型:
我有很多用户(有用户名,密码等),也可以是玩家或裁判或两者兼而有(所以单表inheritance不是一个选项)。 基础模型将是:
class User include DataMapper::Resource property :id, Serial # Other user properties go here end class Player include DataMapper::Resource property :id, Serial # Other player properties go here # Some kind of association goes here end class Referee include DataMapper::Resource property :id, Serial # Other referee properties go here # Some kind of association goes here end DataMapper.finalize
不过,我不确定添加到播放器和裁判的关联类型。 使用belongs_to :user
,可以将多个玩家与同一个用户相关联,这在我的上下文中没有意义。 在RDBMS术语中,我想我想要的是对玩家和裁判员表中的外键的唯一约束。
我如何在DataMapper模型中完成此操作? 我是否必须在validation中自行执行检查?
有不同的方法可以做到这一点。 这是一个选项:
class User include DataMapper::Resource property :id, Serial # Other properties... has 1, :referee, :required => false has 1, :player, :required => false end class Referee include DataMapper::Resource # DON'T include "property :id, Serial" here # Other properties... belongs_to :user, :key => true end class Player include DataMapper::Resource # DON'T include "property :id, Serial" here # Other properties... belongs_to :user, :key => true end
对裁判/球员模特的行为如下:
u = User.create(...) u.referee = Referee.create(...) u.player = Player.create(...) u.player.kick_ball() # or whatever you want to call u.player.homeruns u.referee.flag_play() # or whatever.
看看这是否有效。 我实际上没有测试它,但它应该是好的。
之前的答案不同于:required => false
因为has 1
属性,因此无法识别。
它也令人困惑,因为对于has n
属性,您可以在属性上使用new
权限或以其他方式将其视为集合。 在您的示例中,您会想要编写代码
u = User.create ... u.referee.create ...
但是在has 1
的情况下失败,因为属性是单个值,它开始生命nil
,因此您必须使用前面的答案所指示的方法。 此外,必须明确地将belongs_to
关联变为密钥有点令人困惑。
它似乎确实执行validation并具有正确的关联动作(因此u.save也将保存所引用的Referee
)。 我只是希望它与has n
之间更加一致并且has 1
。