Использование двух имеет одно отношение к одной и той же модели

Я пытаюсь найти лучший способ смоделировать игру по отношению к командам.

Конечная цель - иметь возможность называть такие вещи, как:

@game.winner
@game.loser
@team.games

Первые два отношения работают, а игровое - нет. Используя has_many (см. Ниже), я получаю ERROR: column games.team_id does not exist, с которым я обычно работал бы, используя что-то, эквивалентное :foreign_key => winner_id, но как я могу получить его как winner_id, так и loser_id?

Единственный вариант создать метод в такой модели команд:

def games
  won = Game.where(:winner => id)
  lost = Game.where(:loser => id)
  won + lost
end

Пока что я делаю:

class Game < ActiveRecord::Base
  has_one :winner, class_name: "Team"
  has_one :loser,  class_name: "Team"
end


class Team
  has_many :games
  # or something that actually works
end

person Tom Prats    schedule 03.11.2013    source источник
comment
Возможный дубликат: stackoverflow.com/questions/11873011 /   -  person Waclock    schedule 03.11.2013
comment
Нет, у меня это так, но мне нужны два внешних ключа   -  person Tom Prats    schedule 03.11.2013
comment
Но на самом деле это может быть дубликат рельсовой модели stackoverflow.com/questions/307581/   -  person Tom Prats    schedule 03.11.2013
comment
Я бы сделал что-то похожее на этот ответ, но записал бы его как область условия ИЛИ вместо объединения двух результатов   -  person numbers1311407    schedule 03.11.2013


Ответы (1)


Вы не особо много говорили о проблеме. Но я думаю, вы слишком много работаете. Если команда может сыграть несколько игр, а игра включает в себя более одной команды, тогда вам понадобится отношение "многие ко многим". Для этого требуется третья таблица, и лучше всего использовать отношение has_many :through. Это будет выглядеть примерно так:

class Game < ActiveRecord::Base
  has_many :teams, through: assignment
  has_one :winner, class_name: 'Team', through: :assignment, order: 'score DESC'
  has_one :loser,  class_name: 'Team', through: :assignment, order: 'score ASC'
end

class Team
  has_many :games, through: :assignment
end

class Assignment < ActiveRecord::Base
  belongs_to :game
  belongs_to :team
end

Теперь у вас есть атрибуты победителя и проигравшего, но вам не нужно использовать собственный метод для подсчета игр для команды. Просто скажите team.games.count и аналогично game.teams - это команды, назначенные для игры.

person Gene    schedule 03.11.2013
comment
Значит, мне нужно добавить миграцию для таблицы соединений? - person Tom Prats; 05.11.2013
comment
Что ж, вы действительно хотите создать модель, а не просто миграцию. rails g model Assignment game:references team:references - person Gene; 05.11.2013