このエラーを追跡するのにしばらく時間がかかりましたが、最終的に理由がわかりました。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 がデータをデータベースに挿入する方法に何らかの問題があると思います。cardsgames オブジェクトがないので、card_id を id にプルしてデータベースに挿入しているだけだと思います。これは、cardgames の主キー制約に違反する、同じカードを使用する 2 つのゲームができるまで問題なく機能します。データベースに精通している私は、この問題に対する最初の解決策は、id を削除して cardid と gameid を主キーにすることで、Rails がこの関係の「実際の」定義に従うようにすることでした。移行が2つの主キーを持つことを処理できなかったように見えるため、機能しませんでした(Rails APIがそれをしても大丈夫だと言っているにもかかわらず..奇妙です)。これに対する別の解決策は、「id」を省略することです INSERT INTO ステートメントの列を変更し、データベースに自動インクリメントを処理させます。残念ながら、これを行う方法もわかりません。
それで、これに対する別の回避策はありますか?私が知らない気の利いたRailsのトリックはありますか? それとも、この種の構造は Rails では不可能ですか? 何が悪いのか、いくつかの修正方法を知っているので、これは本当にイライラしますが、Rail フレームワークの制約により、それを行うことができません。