Странное поведение при сохранении экземпляров в Ruby DataMapper - PullRequest
1 голос
/ 08 февраля 2012

только что начал изучать DataMapper для Ruby ORM, я столкнулся с проблемой, которая не дает мне покоя.

Поведение по умолчанию при сохранении экземпляров в DataMapper (через DataMapper :: Resource.save ), насколько я понимаю, при сбое молча, возвращать false из метода сохранения и собирать любыеошибки в сборе ошибок.Пока все хорошо, это работает, как ожидалось.Проблема, с которой я сталкиваюсь, связана с естественными первичными ключами, где установка дубликатов выдаст исключение вместо того, чтобы молча возвращать false из метода сохранения, явно игнорируя текущую настройку rise_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

Первое сохранение при экземпляре, не прошедшем проверку правилом для свойства: description, ведет себя как ожидалось.Третье сохранение экземпляра с дублирующимися ключами, однако, этого не делает, поскольку оно вызывает исключение, а не просто возвращает false.

Почему это?Очевидно, что можно обойти, но это не очень понятно.Является ли случай, когда поведение без вывода сообщений будет применяться только к ошибкам проверки в слое DataMapper, и любые серьезные ошибки из базового хранилища данных будут распространяться как исключения для вызывающей стороны?

Спасибо!

1 Ответ

2 голосов
/ 19 февраля 2012

Как отметил другой пользователь в комментарии, это происходит потому, что установка raise_on_save_failure в false не означает, что исключений не будет. Он всегда будет возвращать false (без исключений) при возникновении ошибок проверки.

Ошибки базы данных, как вы заметили, будут взорваны в виде исключения. Такие ошибки могут возникать из-за большого количества факторов (сбой соединения, отсутствие места на диске), в том числе таких, как дубликат ключа. DataMapper не может знать, обладает ли объект, который вы пытаетесь сохранить, дублирующим ключом, поэтому он просто проверяет его и отправляет в базу данных, где на самом деле происходит ошибка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...