Rails 3.0.11から3.1.3に移行して以来、私は奇妙なエラーが発生しています。ここでは、エラーを再現するスタンドアロンのコードだ:has_many関連のfind_or_initialize_byによって重複エラーが発生する
require 'active_record'
ActiveRecord::Base.establish_connection(
:adapter => 'mysql2',
:username => 'root',
:database => "some_development"
)
class User < ActiveRecord::Base
has_many :favorites
end
class Favorite < ActiveRecord::Base
belongs_to :user
end
u = User.create
# f = u.favorites.find_or_create_by_site_id(123) #=> pass
f = u.favorites.find_or_initialize_by_site_id(123) #=> fail
f.some_attr = 'foo'
f.save!
u.name = 'bar'
u.save! # ActiveRecord::RecordNotUnique will be thrown here!
favorites
テーブルにINSERT
に同じレコードを試みるActiveRecord::RecordNotUnique
を終了します。 (この例では、(user_id、site_id)のペアはお気に入りで一意である必要があります)
興味深いことに、find_or_initialize
の代わりにfind_or_create
を使用した場合、例外は発生しません。
私はautosave_association
が呼び出されたことに気付きましたが、実際にはhas_many :favorites
の代わりにhas_many :favorites, :autosave => false
がエラーを取り除いています。 autosave
について私が気にしたことがないので、:autosave => false
が良いアイデアであるかどうかはわかりません。
何が間違っているのですか、それともRailsのバグですか?誰も私に見てポインタを与えることができますか?
を参照してくださいUserモデルは、フィールドの一意性の検証を持っていますか?また、コメント行の '#=> pass'の隣には何がありますか?一度に2つのバージョンのお気に入りを作成しようとしていますか? – Batkins
はい、Userモデルには一意性を含む一連の検証がありますが、どのように関係するかはわかりません。あなたがfind_or_initializeの代わりにfind_or_createの行にコメントインすると、私の質問に記述されているように、エラーなしで渡されるはずです。 – kenn
これを試すことができますか? 'u.save!'の代わりに 'u.save'を実行し、' puts u.errors'または 'p u.errors'を実行します。エラーは何ですか?私はこれが、(あなたがフィードされている属性を持たない汎用の 'User.create'を使用しているので)一意性の検証の1つをパスしないユーザーを作成しているという問題であると感じています。 – Batkins