【问题标题】:Tables associations best practices in Rails?Rails 中的表关联最佳实践?
【发布时间】:2012-08-03 09:44:09
【问题描述】:

刚接触 Rails,管理过一些简单的项目,但现在正在处理更复杂的表之间的关联,希望能得到一些帮助。

该场景最好与体育比赛相关。假设我们有

1) 一个团队(拥有多个玩家)

2) 球员(属于球队)

3) 一场比赛——现在变得很棘手。

一场比赛将有:2 支球队和 22 名球员(每边 11 名)参加比赛。此外,与每位球员相关联的是他们的比赛得分(例如,射门次数、进球数、得分等)

创建这种关联的最佳做法是什么?任何提示将不胜感激。

【问题讨论】:

  • 这是一个相当复杂的问题。它还取决于您将如何使用(查询)您尚未描述的数据。所以这个问题有点难回答。
  • 我不确定我应该如何查询数据。我想我会在每场比赛中添加“比赛日期”和“场地”。这应该足以拉开比赛(即显示所有在 2012 年 9 月 27 日进行的比赛)。

标签: ruby-on-rails database activerecord relationship


【解决方案1】:

型号

app/models/team.rb

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

app/models/player.rb

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

app/models/match.rb

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

app/models/team_match.rb

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

app/models/player_match.rb

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

迁移

db/migrate/create_matches.rb

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

db/migrate/create_players.rb

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

db/migrate/create_teams.rb

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

db/migrate/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

db/migrate/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:抱歉版本太多了,我完全低估了这个问题。

【讨论】:

  • 您将如何存储射门次数、进球数??
  • 但是使用has_many :players, through: :teams,您无法将其存储在单个玩家的级别上,因为与玩家的关联会通过团队进行。
  • 我是说你的has_many through 没有多大意义。更不用说您在匹配表中发布了包含player_id 的迁移。请参阅:guides.rubyonrails.org/… 如果您仍然认为这是正确的,请举例说明您将如何使用此代码。
  • 你在匹配表中有player_id这一事实表明belongs_to玩家,这显然是不正确的。我认为你需要另一个模型。例如。 PlayerMatchScorebelongs_to :matchbelongs_to :player。然后在Matchhas_many :player_match_scores。类似的东西。
  • 没问题。模拟这样的情况相当复杂。我还在想我该怎么做。
【解决方案2】:

玩家拥有并属于多场比赛

该表应包含参加该比赛的球员的详细信息。例如他效力于哪支球队,从哪一分钟开始(因为球员可以更换)等等。

【讨论】:

  • 假设像板球这样的运动,其中球员自始至终都是固定的,不能改变。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 2011-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多