5

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のバグですか?誰も私に見てポインタを与えることができますか?

+0

を参照してくださいUserモデルは、フィールドの一意性の検証を持っていますか?また、コメント行の '#=> pass'の隣には何がありますか?一度に2つのバージョンのお気に入りを作成しようとしていますか? – Batkins

+0

はい、Userモデルには一意性を含む一連の検証がありますが、どのように関係するかはわかりません。あなたがfind_or_initializeの代わりにfind_or_createの行にコメントインすると、私の質問に記述されているように、エラーなしで渡されるはずです。 – kenn

+0

これを試すことができますか? 'u.save!'の代わりに 'u.save'を実行し、' puts u.errors'または 'p u.errors'を実行します。エラーは何ですか?私はこれが、(あなたがフィードされている属性を持たない汎用の 'User.create'を使用しているので)一意性の検証の1つをパスしないユーザーを作成しているという問題であると感じています。 – Batkins

答えて

5

f.save!を電話してみましたか? u.save!は、お気に入りとユーザーの両方を保存する必要があります。

> f = u.favorites.find_or_initialize_by_site_id(123) 

> u.favorites.include?(f) 
==> false 

> f2 = u.favorites.build(:site_id => 123) 

> u.favorites.include?(f2) 
==> true 

あなたが作成した新しいお気に入りfは、別のオブジェクトであることがわかりました。したがって、あなたはfを保存しますが、u.favouritesに保存されていない別のお気に入りもあります。したがって、uを保存すると(お気に入りも保存する)一意でないエラーが発生する

これは、Rails 3.1で新たに導入されたバグかどうかはわかりません。それは意図的なものかもしれません。 Railsの3.0 find_or_initialize_byで

は、アレイ

> f = u.favorites.find_or_initialize_by_site_id(123) 

> u.favorites 
==> [] 

はバグのように見える移入されませんでした - https://github.com/rails/rails/pull/3610

+0

'u.save!'は 'f.save! 'のコードの遠い場所にあり、' u'がダーティーされずにスキップされる可能性があるので、そこになければなりません。私はそれがエラーを起こす理由を知りたい。 – kenn

関連する問題