2009-12-21 3 views
32

Мне нужно создать строку в таблице как билетов, так и пользователей ... Мне просто нужно знать, как обрабатывать, если транзакция завершится с ошибкой.Обработка ошибок в транзакциях ActiveRecord?

@ticket.transaction do 
    @ticket.save! 
    @user.save! 
end 
    #if (transaction succeeded) 
     #..... 
    #else (transaction failed) 
     #...... 
    #end 

На стороне записки я просто хотел бы поблагодарить всех, кто участвует в переполнения стека для помощи дизайнера узнать больше программирования ... Я ценю время вы, ребята, взять из вашего дня, чтобы ответить на такие вопросы, как N00b это :)

ответ

50

Если вы используете сохранение! метод с ударом (восклицательный знак), приложение будет генерировать исключение, когда сбой не удастся. Затем вам придется поймать исключение, чтобы справиться с этим сбоем.

begin 
    @ticket.transaction do 
    @ticket.save! 
    @user.save! 
    end 
    #handle success here 
rescue ActiveRecord::RecordInvalid => invalid 
    #handle failure here 
end 
+0

Большое спасибо Мэтт, я ценю это :) – Kevin

+7

Сделка, подобная первой в первом фрагменте (без исключений), вовсе не является транзакцией Rails. Операция, подобная той, что во втором фрагменте, должна спасти все исключения (rescue => e), сбой ручного управления и, возможно, снова включить то же исключение. – Ando

+7

Извините Ando, ​​но это явно транзакция ActiveRecord, о чем свидетельствует метод «транзакция». Основная точка транзакции заключается в том, что первое действие (сохранение билета) отменяется, если второе не удается. Это был очень простой пример для нового разработчика ... очевидно, что это заменит комментарий обработкой отказа. Спасибо, что поделились своей точкой зрения на обработку ошибок, но пример исходит от «Agile Web Development with Rails», как писал первый автор Rails! Поэтому я бы сделал исключение из вашей характеристики того, что не генерирует исключение, а не Rails – MattMcKnight

0

я тоже новичок, но я считаю, что вы можете проверить @ ticket.errors и @ user.errors и проверки в соответствии с их ответами

также сохранить метод должен возвращать логическое значение, которое определяет если сохранение было успешным

1

для меня, используя Rails 2.3.8 следующее было лучшим решением:

#Important this have to be nil 
result = nil 

@ticket.transaction do 
    result[true, 'Well done'] 

    result = [false, "Ticket can't be saved"] unless @ticket.save! 
    raise ActiveRecord::Rollback unless result[0] 

    result = [false, "User can't be saved"] unless @user.save! 
    raise ActionRecord::Rollback unless result[0] 
end 

if result[0] 
    flash[:notice] = result[1] 
    #... 
else 
    flash[:warning] = result[1] + "<br> Not so well done" 
end 

Убедитесь, что и инициализировать результат, как ноль, так что вы можете принять изменения, сделанные внутри сделки после того, как Откат!

Смежные вопросы