Ассоциации объектов с использованием datamapper - PullRequest
1 голос
/ 04 ноября 2011

Я пытаюсь назначить игроков в клуб.В клубе есть 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

end

В конце сценария я ожидаю, что все клубы22 игрока.Почему это не так?

РЕДАКТИРОВАТЬ: В конце скрипта я получаю только 22 игрока, назначенных в последний клуб (20) и 10000 игроков генерируется

1 Ответ

0 голосов
/ 04 ноября 2011

Задача 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 знает о вашей индивидуальной игре.одна ассоциация и последнее назначение «выигрывает».

...