RoR3模型关联(游戏属于两个玩家)

时间:2011-10-06 19:22:23

标签: ruby-on-rails ruby-on-rails-3 associations model-associations rails-models

我对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,created_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)?

谢谢!

3 个答案:

答案 0 :(得分: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

如果你这样做,你仍然需要指定:class_name =&gt;每个belongs_to调用的'播放器'选项。

答案 1 :(得分:2)

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

我最终使用了与roboles建议不同的方法,因为我需要一种方法来跟踪玩家与游戏之间的关系。

首先我添加了一个名为Seats的第三个模型,然后设置我的Player和Game模型以具有has_many:通过以下关系:

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

我有兴趣了解改善这方面的任何方法。

答案 2 :(得分:0)

在你的游戏类中添加2个字段,如:

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

因此,这意味着您的数据库player_one int, player_two int

中有2个整数字段

其他模特不应该改变。