Лучшие практики ассоциаций таблиц в Rails?

Очень новичок в Rails, управлял несколькими простыми проектами, но теперь перешел к более сложным ассоциациям между таблицами и надеялся на некоторую помощь.

Сценарий лучше всего может быть связан со спортивным матчем. скажем, у нас есть

1) Команда (имеет_много игроков)

2) Игрок (принадлежит команде)

3) Матч - теперь это становится сложнее.

В Матче участвуют: 2 команды и 22 игрока (по 11 с каждой стороны), которые принимают в нем участие. Кроме того, с каждым игроком будут связаны его очки за матч (например, удары по воротам, забитые голы, очки и т. д.).

Что было бы наилучшей практикой для создания такого рода ассоциации? Мы будем очень благодарны за любые советы.


person Kopty    schedule 03.08.2012    source источник
comment
Это довольно сложная проблема. Это также зависит от того, как вы будете использовать (запрашивать) свои данные, которые вы не описали. Так что ответить на этот вопрос довольно сложно.   -  person Mischa    schedule 03.08.2012
comment
Я не был точно уверен, как я должен запрашивать данные. Думаю, я добавлю дату игры, а также место проведения каждого матча. Этого должно быть достаточно, чтобы вытащить матчи (т.е. показать все матчи, сыгранные 27 сентября 2012 г.).   -  person Kopty    schedule 03.08.2012


Ответы (2)


Модели

приложение/модели/команда.рб

class Team < ActiveRecord::Base
    has_many :players, inverse_of: :team
    has_many :team_matches
    has_many :matches, through: :team_matches
end

приложение/модели/player.rb

class Player < ActiveRecord::Base
    belongs_to :team, inverse_of: :player
    has_many :player_matches
    has_many :matches, through: :player_matches
end

приложение/модели/match.rb

class Match < ActiveRecord::Base
    has_many :players, through: :player_matches
    has_many :teams, through: :team_matches
end

приложение/модели/team_match.rb

class TeamMatch < ActiveRecord::Base
    belongs_to :team
    belongs_to :match
end

приложение/модели/player_match.rb

class PlayerMatch < ActiveRecord::Base
    belongs_to :player
    belongs_to :match
end

Миграции

БД/мигрировать/create_matches.rb

class CreateMatches < ActiveRecord::Migration
  def change
    create_table :matches do |t|
      t.datetime :happened_at
      t.timestamps
    end
  end
end

БД/мигрировать/create_players.rb

class CreatePlayers < ActiveRecord::Migration
  def change
    create_table :players do |t|
      t.string :name
      t.timestamps
    end
  end
end

БД/мигрировать/create_teams.rb

class CreateTeams < ActiveRecord::Migration
  def change
    create_table :teams do |t|
      t.string :name
      t.timestamps
    end
  end
end

БД/мигрировать/create_player_matches.rb

class CreatePlayerMatches < ActiveRecord::Migration
  def change
    create_table :player_matches do |t|
      t.integer :match_id
      t.integer :player_id
      t.integer :player_shots_on_goal
      t.integer :player_goals_scored
      t.timestamps
    end
  end
end

БД/мигрировать/create_team_matches.rb

class CreateTeamMatches < ActiveRecord::Migration
  def change
    create_table :team_matches do |t|
      t.integer :match_id
      t.integer :team_id
      t.integer :team_points
      t.timestamps
    end
  end
end

Edit1: @Mischa должен поделиться здесь! :)

Edit2: Извините за множество версий, я полностью недооценил эту проблему.

person Marcelo De Polli    schedule 03.08.2012
comment
А как вы будете хранить удары по воротам, забитые голы?? - person Mischa; 03.08.2012
comment
Эти поля входят в таблицу соответствия. Но это не отображается в моделях, это все в миграциях, которые формируют схему базы данных. Я собираюсь добавить пример. - person Marcelo De Polli; 03.08.2012
comment
Но с has_many :players, through: :teams вы не можете сохранить это на уровне отдельного игрока, потому что ассоциация с игроком проходит через команды. - person Mischa; 03.08.2012
comment
Точно. Однако это предположение можно опровергнуть. Судя по формулировке постера, так оно и было. - person Marcelo De Polli; 03.08.2012
comment
Я говорю, что ваше has_many through не имеет особого смысла. Тем более теперь, когда вы опубликовали миграцию, содержащую player_id в таблице соответствий. См.: guides.rubyonrails.org/ Если вы все еще думаете что это правильно, пожалуйста, приведите пример, как вы будете использовать этот код. - person Mischa; 03.08.2012
comment
Тот факт, что у вас есть player_id в таблице матчей, предполагает belongs_to игрока, что явно неверно. Я думаю, вам нужна другая модель. Например. PlayerMatchScore, belongs_to :match и belongs_to :player. А потом в Match: has_many :player_match_scores. Что-то такое. - person Mischa; 03.08.2012
comment
Хм, да... еще раз спасибо. Попробую придумать что-нибудь получше. - person Marcelo De Polli; 03.08.2012
comment
Без проблем. Смоделировать такую ​​ситуацию довольно сложно. Я все еще думаю о том, как бы я это сделал. - person Mischa; 03.08.2012
comment
Ну вот! Думаешь, теперь это сработает, Миша? Это все еще кажется странным, потому что в таблицах соединений есть дополнительные поля, кроме идентификаторов... - person Marcelo De Polli; 03.08.2012
comment
Я думаю либо так, либо с использованием дополнительной полиморфной модели, которая работает как посредник между матчами и игроками/командами. Дай нам знать, как все получится, Копти. - person Marcelo De Polli; 03.08.2012
comment
Это фантастика. Хотел бы я, чтобы у меня было больше, чем голос, чтобы дать вам, добрые люди. Спасибо за такой подробный и фантастический ответ. - person Kopty; 03.08.2012

Игрок имеет и принадлежит ко многим совпадениям

Эта таблица должна содержать информацию об игроке, играющем в этом матче. Например, за какую команду он играл, с какой минуты (т.к. игроки могут меняться) и т.д.

person Luc Franken    schedule 03.08.2012
comment
Предположим, например, в таком виде спорта, как крикет, в котором игроки постоянно фиксированы и не могут меняться. - person Kopty; 03.08.2012