1

真的是 Ruby on Rails 3 的新手,我正在开发一个简单的国际象棋游戏应用程序。我计划创建以下模型:

rails g model Player name:string
rails g model Game player_id_white:int player_id_black:int title:string
rails g model Comment player_id:int game_id:int comment_data:text
rails g model Move game_id:int player_id:int move_data:string

假设它们都有:id:int:primary_key、c​​reated_at:datetime、updated_at:datetime。我还省略了“password_hash”等字段。我的问题在于关联,而不是让应用程序运行所需的字段。

class Player < ActiveRecord::Base
  has_many :games #some have player_id_black, others as player_id_white
  has_many :comments
  has_many :moves
end

class Game < ActiveRecord::Base
  has_many :comments
  has_many: moves
  **belongs_to :player1??**
  **belongs_to :player2??**
end

class Comment < ActiveRecord::Base
  belongs_to :player
  belongs_to :game
end

class Move < ActiveRecord::Base
  belongs_to :player
  belongs_to :game
end

问题:

1)我想将一个游戏链接到两个玩家,我该如何指定这种关系?
2)我是否必须在'rails generate model'中指定game_id:int之类的东西,还是在我做关系时它是隐含的(belongs_to:player,has_many:games)?

谢谢!

4

3 回答 3

4

鉴于上述迁移,您可能希望按如下方式设置您的游戏模型:

class Game < ActiveRecord::Base
  has_many :comments
  has_many :moves
  belongs_to :white_player, :class_name => 'Player', :foreign_key => 'player_id_white'
  belongs_to :black_player, :class_name => 'Player', :foreign_key => 'player_id_black'
end

这将使用您的自定义外键,并使您能够将每个关联链接为单个 belongs_to 调用!

或者,如果您希望 rails 来“猜测”foreign_key 设置,您需要像这样设置迁移:

rails g model Game white_player_id:integer black_player_id:integer title:string

如果你这样做,你仍然需要为每个 belongs_to 调用指定 :class_name => 'Player' 选项。

于 2011-10-06T19:28:37.207 回答
2

我在同一条船上:Rails 新手和构建国际象棋应用程序。我开始使用 Players 和 Games 之间的 has_and_belongs_to_many 关系,但我无法弄清楚如何正确地以这种方式为白人和黑人玩家角色建模。

我最终使用了与 roboles 建议的方法不同的方法,因为我需要一种方法来遵循从玩家到游戏的关系。

首先,我添加了第三个模型,称为 Seats,然后将我的 Player 和 Game 模型设置为具有 has_many :through 关系,例如:

class Game < ActiveRecord::Base
  has_many :seats
  has_many :players, :through => :seats
end

class Player < ActiveRecord::Base
  has_many :seats
  has_many :games, :through => :seats
end

class Seat < ActiveRecord::Base
  belongs_to :game
  belongs_to :player
end

这设置了模型,以便 game.players 和 player.games 工作。

为了跟踪白人和黑人球员,我在座位表中添加了一个颜色列:

create_table "seats", :force => true do |t|
  t.integer  "player_id"
  t.integer  "game_id"
  t.integer  "color"
  t.datetime "created_at", :null => false
end

然后在游戏模型中我添加了一些辅助方法,以便我可以使用 game.white_player 获取白人玩家并使用 game.white_player = foo 设置

class Game < ActiveRecord::Base
...
def white_player
  Player.joins(:games).where(:seats => {:color => 0, :game_id => self.id}).first
end

def white_player=(player)
  self.players << player

  s = self.seats.find_by_player_id(player)
  s.color = 0
  s.save
end

我不确定这是否是最好的方法,但它似乎符合我的要求:

game.players # returns game's players
player.games # returns player's games
game.white_player # returns the white player
game.white_player = player # sets the white player

我很想知道有什么方法可以改进这一点。

于 2013-01-28T02:36:38.700 回答
0

在您的 Game 类中添加 2 个字段,例如:

belongs_to :player_one, :class_name => "Player"
belongs_to :player_two, :class_name => "Player"

所以这意味着您的数据库中有 2 个整数字段player_one int, player_two int

其他模型不应该改变。

于 2011-10-06T19:29:02.003 回答