使用datamapper的对象关联

时间:2011-11-04 16:18:12

标签: ruby rake datamapper padrino

我正在尝试将球员分配到俱乐部。 俱乐部有n个球员,球员属于俱乐部。 一个俱乐部只能有不到23名球员,不超过2名球员在同一位置上比赛。

clubs = Club.all #Club is a datamapper object. Returns 20 clubs
to_generate = 10000
while (to_generate > 0)
  p = Player.new #Player is a datamapper object
  p.position = position #position is a random integer defined elsewhere

  clubs.each do |club|
    count = 0
    club.players.each do |club_player|
      if (club_player.position == p.position)
        count += 1
      end
    end
    if (count < 2 && club.players.length < 22)
      club.players << p
      p.club = club
    end
  end
  p.save
  to_generate -= 1

在剧本结束时,我希望所有俱乐部都有22名球员。为什么不是那样的?

编辑:在剧本结束时,我只有22名玩家被分配到最后一个俱乐部(20)和10000名玩家生成

1 个答案:

答案 0 :(得分:0)

问题1:您可以超过每个团队和每个位置的最大玩家

这些行

if (count < 3 && club.players.length < 23)
  club.players << p
  p.club = club
end

可以概括为“如果俱乐部的球员数少于23人,而且该位置的球员少于3人,则可以将球员添加到俱乐部。”

这意味着它允许你再添加一个...总共3个位置,23个团队。所以这部分逻辑是错误的。相反,你想要

if (count < 2 && club.players.length < 22)

问题2:随机数可能无法保证您拥有合适类型的玩家

如果该位置是随机生成的,则无法确定您是否拥有足够的正确类型的玩家。例如,如果随机数始终为2,该怎么办?你永远不会得到一个完整的团队。

问题3:一旦分配了一名球员,你就会继续尝试其他俱乐部

一旦你指定一名球员,你就不应该再看看俱乐部了。为此,您需要突破each块。

if (count < 3 && club.players.length < 23)
  club.players << p
  p.club = club
  break
end

即使您为同一个玩家多次调用club.players << p,DataMapper也会知道您的一对一关联,最后一个分配“胜出”。