Rails模型关联问题:Game模型关联两个User的实现困扰
Hey there! Let's work through the issues in your Game model setup—you're close, but there are a few key mistakes throwing things off:
1. Wrong Association Type: has_one vs belongs_to
Your Game table stores user1_id and user2_id as foreign keys, which means each Game belongs to two User instances, not the other way around. Using has_one here is backwards: that would imply the User table has a game_id column pointing to a single Game, which isn't your use case. Switch these to belongs_to instead.
2. Typo-Ridden & Redundant Validations
Your validation rules have typos and unnecessary extra checks:
blank: falseshould beallow_blank: false(but you don't even need this)nill: falseis a typo—it's supposed to beallow_nil: false- The
presence: truerule already covers both "not blank" and "not nil", so you can strip those extra flags entirely.
3. Dangerous dependent: :destroy Placement
Adding dependent: :destroy to these belongs_to associations would mean deleting a Game would delete the associated Users. That's almost certainly not what you want—you don't want to nuke a user's account just because one of their games gets removed. If you need to handle cleanup when a User is deleted, add the dependent rule on the User model side, or use dependent: :nullify here to set the game's user IDs to null if the user is deleted.
Corrected Game Model Code
class Game < ApplicationRecord has_secure_token # @!group RELATIONS has_many :turns, dependent: :destroy has_many :play_cards, dependent: :destroy belongs_to :user1, class_name: 'User' belongs_to :user2, class_name: 'User' # @!endgroup # @!group VALIDATORS validates :user1_id, presence: true validates :user2_id, presence: true # Optional: Add a check to prevent a user from playing against themselves validate :users_must_be_unique private def users_must_be_unique errors.add(:base, "A game can't have the same user for both players") if user1_id == user2_id end # @!endgroup end
Bonus: Reverse Associations on User Model
If you want users to be able to access all games they're part of, add these to your User model:
class User < ApplicationRecord # Get games where this user is player 1 has_many :games_as_player1, class_name: 'Game', foreign_key: 'user1_id', dependent: :nullify # Get games where this user is player 2 has_many :games_as_player2, class_name: 'Game', foreign_key: 'user2_id', dependent: :nullify # Optional: Combine both into a single handy association def games Game.where("user1_id = ? OR user2_id = ?", id, id) end end
Quick Migration Check
Make sure your games table has the required foreign key columns. If not, run this migration:
rails generate migration AddPlayerReferencesToGames user1:references user2:references rails db:migrate
内容的提问来源于stack exchange,提问作者Alexis CHEVREUX

