我花了一段时间才找到这个错误,但我终于找到了原因。我正在使用 Rails 框架对纸牌游戏进行建模。目前我的数据库看起来(大部分)是这样的:
cards cards_games games
----- ----------- -----
id id id
c_type card_id ...
value game_id other_stuff
Rails ActiveRecord card.rb 和 game.rb 目前看起来像这样
#card.rb
class Card < ActiveRecord::Base
has_and_belongs_to_many :player
has_and_belongs_to_many :game
has_and_belongs_to_many :cardsInPlay, :class_name => "Rule"
end
#game.rb
class Game < ActiveRecord::Base
has_and_belongs_to_many :cards
has_many :players
has_one :rules, :class_name => Rule
end
当我尝试运行一个游戏并且有多个游戏(超过 1 个)时,我收到错误
ActiveRecord::StatementInvalid in GameController#start_game
# example
Mysql::Error: Duplicate entry '31' for key 1: INSERT INTO `cards_games` (`card_id`, `id`, `game_id`) VALUES (31, 31, 7)
每次操作失败时,cardid == id。我认为这与 Rails 如何将数据插入数据库有关。由于没有 cardgames 对象,我认为它只是将 card_id 拉入 id 并将其插入数据库。这工作正常,直到您有两个游戏使用同一张卡片,这违反了卡片游戏的主键约束。由于对数据库非常熟悉,我对这个问题的第一个解决方案是尝试通过删除 id 并将 cardid 和 gameid 作为主键来强制 rails 遵循这种关系的“真实”定义。它不起作用,因为迁移似乎无法处理具有两个主键的问题(尽管 Rails API 说可以这样做......很奇怪)。另一个解决方案是省略“id” INSERT INTO 语句中的列,并让数据库处理自动增量。不幸的是,我也不知道该怎么做。
那么,是否有另一种解决方法呢?有一些我不知道的漂亮的 Rails 技巧吗?或者这种结构在 Rails 中是不可能的?这真的很令人沮丧,因为我知道出了什么问题,而且我知道有几种方法可以修复它,但是由于 Rail 框架的限制,我无法做到。