2012-02-08 2 views
1

Ruby ORM 용 DataMapper를 처음 보았습니다. 끝까지 혼란스럽게하는 문제가 발생했습니다.Ruby DataMapper에 인스턴스를 저장할 때 이상한 동작이 발생했습니다.

DataMapper (DataMapper :: Resource.save 통해)를 통해 인스턴스를 저장할 때의 기본 동작은 오류가 발생하면 save 메서드에서 false를 반환하고 오류 컬렉션에서 오류를 수집합니다. 지금까지 그렇게 좋았습니다. 이것은 예상대로 작동합니다. 내가 본 문제는 자연 기본 키를 사용하는 것입니다. 중복 설정의 경우 거짓을 save 메서드에서 자동으로 반환하는 대신 예외를 throw하는 대신 예외를 throw합니다. 즉, 현재 설정 인 raise_on_save_failure을 무시합니다. 다음 스 니펫을 고려하십시오.

require 'data_mapper' 

class Thing 
    include DataMapper::Resource 
    property :name , String, :key=> true 
    property :description, String, length: 2..5 
end 

DataMapper.setup :default, "sqlite:memory" 
DataMapper.finalize 
DataMapper.auto_migrate! 

#Create a thing and have it properly silently fail saving 
t1=Thing.new(:name=>"n1",:description=>"verylongdescription") 

t1.save #ok 
puts("t1 is saved:"+t1.saved?.to_s) 
t1.errors.each do |e| 
    puts e 
end 

#Create two things with the same key, and fail miserably in silently failing the second  save... 
t1=Thing.new(:name=>"n1",:description=>"ok") 
t2=Thing.new(:name=>"n1",:description=>"ok") 

t1.save #ok 
t2.save #not ok, raises Exception event though it shouldn't? 

puts("t2 is saved:"+t1.saved?.to_s) 
t2.errors.each do |e| 
    puts e 
end 

: 설명 특성에 대한 유효성 검증 규칙에 실패한 인스턴스의 첫 번째 저장이 예상대로 작동합니다. 중복 키가있는 인스턴스의 세 번째 저장은 false를 반환하는 대신 멋지게 실행을 발생시키기 때문에 저장하지 않습니다.

왜 이런가요? 분명히 해결할 수 있지만 분명하지는 않습니다. 자동 작동이 DataMapper 레이어의 유효성 검사 오류에만 적용되며 기본 데이터 저장소의 하드 오류가 호출자에게 예외로 전파되는 경우입니까?

감사합니다.

+0

유효성 검사 최종 사용자 오류를 catch하면 중복 키가 데이터베이스로 내려 가서 프로그래머 오류가 발생합니다. 0으로 나누거나'save' 과정에서'nil'을 제대로 처리하지 않으면 같은 이유로 예외가 발생합니다. –

+0

예, 이것은 구별되는 의미가 있습니다. 이제 DataMapper에서 유효성 검사의 목적과 침묵/비침 해적 행동을 조금 더 이해합니다. 그런 다음 위의 예에서 고유 한 유효성 검사를 추가 한 경우이를 추측합니다. – osmbergs

+0

불행히도 고유성 유효성 검사는 경쟁 조건의 영향을 받기 때문에 충분하지 않으므로 데이터베이스에도 고유 한 제약 조건이 필요하지만 경쟁 조건이 발생하면 예외가 발생합니다. –

답변

2

다른 사용자가 설명에서 지적한 바와 같이 raise_on_save_failure에서 false으로 설정한다고해서 예외가 발생하지 않는다는 것을 의미하지는 않습니다. 유효성 검사 오류가 발생하면 항상 false을 반환합니다 (예외는 아님).

데이터베이스 오류는 사용자가 알듯이 예외의 형태로 폭발합니다. 이러한 오류는 복제 키와 같이 평범한 것을 포함하여 많은 수의 요인 (연결에 실패하고 디스크 공간이 없음)으로 인해 발생할 수 있습니다. DataMapper는 저장하려고하는 객체가 중복 키를 가지고 있는지 여부를 알 수 없으므로 실제로 검증하고 오류가 실제로 발생하는 데이터베이스로 보냅니다.

관련 문제