0

Je suis vraiment nouveau à Ruby on Rails 3 et je travaille sur une application de jeu d'échecs simple. Je prévois de créer les modèles suivants:RoR3 associations de modèles (jeu appartient à deux joueurs)

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 

Supposons qu'ils ont tous: id: int: primary_key, created_at: datetime, updated_at: datetime. J'ai également omis des champs comme 'password_hash' et d'autres. Mon problème est avec les associations, pas tellement avec les champs dont j'ai besoin pour faire fonctionner l'application.

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 

Questions:

1) Je veux lier un jeu à deux joueurs, comment puis-je préciser cette relation?
2) Dois-je spécifier des choses comme game_id: int dans 'rails generate model' ou est-ce implicite quand je fais les relations (belongs_to: player, has_many: games)?

Merci!

Répondre

3

compte tenu de la migration ci-dessus vous voulez définir votre modèle de jeu comme suit:

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 

Cela utilisera vos clés étrangères personnalisées, et vous permettent de relier chaque association comme un seul belongs_to appeler!

Sinon, si vous voulez des rails de « deviner » le foreign_key paramètre que vous devez configurer votre migration comme ceci: Si vous faites cela,

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

vous auriez encore besoin de préciser le: class_name => Option 'Player' pour chacun des appels belongs_to.

+0

J'aime mieux votre nom! Agréable. –

+0

Salut Cody, J'ai édité le post pour inclure une option de migration différente aussi, désolé oublié de l'inclure dans mon post original :) – roboles

+0

Maintenant, est-il possible de faire @ player.games? Comment pourrait-on mettre cela en place? –

0

Dans votre classe de jeu ajouter 2 champs comme:

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

Donc, ce que vous avez 2 implique des champs entiers dans votre DB player_one int, player_two int

Les autres modèles doivent changer shouldnt.

2

Je suis dans le même bateau: nouveau sur Rails et construction d'une application d'échecs. J'ai commencé en utilisant une relation has_and_belongs_to_many entre les joueurs et les jeux, mais je n'arrivais pas à comprendre comment modéliser correctement les rôles des joueurs blancs et noirs de cette façon. J'ai fini par utiliser une approche différente de celle suggérée par les roboles parce que j'avais besoin d'un moyen de suivre la relation entre le joueur et les jeux.

D'abord, j'ajouté un troisième modèle appelé sièges, puis configurer mes modèles de joueurs et du jeu d'avoir une has_many: à travers une relation comme:

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 

Ceci met en place le modèle de telle sorte que game.players et player.games travail.

Pour suivre le joueur blanc et noir, j'ai ajouté une colonne pour la couleur dans la table des sièges:

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 

Ensuite, dans le modèle de jeu j'ai ajouté quelques méthodes d'aide afin que je puisse obtenir le joueur blanc avec le jeu .white_player et défini avec le jeu.white_player = toto

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 

Je ne suis pas sûr que ce soit la meilleure approche, mais il semble répondre à mes besoins:

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 

Je serais intéressé de connaître des façons d'améliorer cette .

Questions connexes