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이 좋은 아이디어인지 확실하지 않습니다.

내가 뭘 잘못하고 있니? 아니면 레일즈 버그 야? 누구든지 나를 볼 포인터를 줄 수 있습니까?

+0

합니까 사용자 모델을 볼 수는 필드의 고유성에 대한 유효성 검사가? 또한 그것의 옆에'# => pass'로 주석 처리 된 행은 무엇입니까? 한번에 두 가지 버전의 즐겨 찾기를 만들려고하십니까? – Batkins

+0

예, User 모델에는 고유성을 비롯한 일련의 유효성 검사가 있지만 관련성이 확실하지 않습니다. find_or_initialize 대신 find_or_create 행에 주석 처리하면 내 질문에 설명 된대로 오류없이 전달됩니다. – kenn

+0

이것을 시도해 볼 수 있습니까?'u.save! '대신'u.save'를 실행 한 다음'puts u.errors' 또는'p u.errors'를 수행하십시오. 오류는 무엇입니까? 나는 이것이 유일성에 대한 검증 중 하나를 통과시키지 않는 사용자를 생성하는 문제라고 생각한다. 왜냐하면 (사용자가 속성을 입력하지 않고 일반'User.create'를 사용하기 때문에). – 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은 별도의 개체라는 점을 생각합니다. 그러므로 u.favourites에 저장되지 않은 또 다른 즐겨 찾기가있는 동안 f를 저장하게됩니다. 따라서 u를 저장하면 (즐겨 찾기를 저장하는) 비 고유 오류가 발생합니다.

이것이 Rails 3.1에서 새로 도입 된 버그인지 확실하지 않습니다. 그것은 의도적 일 수 있습니다.

> f = u.favorites.find_or_initialize_by_site_id(123) 

> u.favorites 
==> [] 

버그처럼 보이는 배열이 채워지지 않은 레일 3.0 find_or_initialize_by에서

-https://github.com/rails/rails/pull/3610

+0

'u.save!'가'f.save! '의 코드에서 멀리 떨어져 있기 때문에'u.save!'가 있어야하고'u'가 더럽혀지지 않고 건너 뛸 수있는 기회가 있습니다. 나는 그것이 오류를 일으키는 이유를 알고 싶다. – kenn

관련 문제