Заставьте сохранить! операция провалилась - PullRequest
0 голосов
/ 20 августа 2009

У меня есть ImagesController, который запускает нетривиальную операцию сохранения. Вот фон высокого уровня:

В моем приложении есть несколько разных типов физических файлов. Каждый из этих belongs_to a Binary. Конечно, файлы могут быть созданы, и этот процесс включает в себя загрузку физического файла во временное местоположение, возможно проверку физического файла (по размеру, типу и т. Д.) И затем, без проблем, перемещение файла в постоянное место перед созданием записей базы данных в соответствующих таблицах (для целей моего вопроса используем images и binaries).

Image принадлежит Binary, а есть BinaryObserver, который наблюдает за классом Image. В этом классе наблюдателя есть метод before_create(), который указывает классу Binary загрузить физический файл изображения и сохранить соответствующую запись в базе данных (с именем, путем, информацией URI и т. Д.).

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

В методе create() моего контроллера у меня есть:

if @image.save!
  flash[:notice] = "Successfully created image."
  redirect_to @image
else
  flash[:notice] = "Upload failed."
  render :action => 'new'
end

Я не могу понять, как вызвать блок else. В моем BinaryObserver классе у меня есть:

def before_create( model )
    binary = Binary.new.upload( model.upload )

    if !model.respond_to?( 'before_file_save' ) || model.before_file_save()
        binary         = binary.store()
        model.binary_id = binary.id
        model.active    = 1

        return true
    else
        # binary.destroy()
        File.delete( File.join( Rails.root, binary.path ) )
        return false
    end
end

В данный момент Image.before_file_save() просто возвращает false. Физический файл удаляется, но сохранение не приводит к ошибке, и мой контроллер отображает сообщение об ошибке, что его метод show() не может найти изображение (что имеет смысл, так как изображение не было сохранено, а физический файл был удален ).

Как заставить принудительно завершиться операцию сохранения, если метод класса наблюдателя 'before_create() возвращает false?

Спасибо.

Ответы [ 2 ]

1 голос
/ 20 августа 2009

Насколько я понимаю, использование синтаксиса bang (!) В методах Model вызовет исключение в случае сбоя операции. Очевидно, что сохранение не дает сбоя, но наблюдатель должен сообщить контроллеру, что что-то пошло не так. Я бы использовал тот же AR-способ, за исключением:

begin
    @image.save!
    flash[:notice] = "Successfully created image."
    redirect_to @image
rescue YourObserverException => e
    flash[:notice] = "Upload failed."
    render :action => 'new'
end

Это означало бы, что наблюдатель не возвращает true, но поднимает YourObserverException, если загрузка не удалась (где вы returning false).

0 голосов
/ 20 августа 2009

Ваш Обозреватель все еще работает внутри Транзакции ActiveRecord, которая создается в основном сверху. Таким образом, БД мудрый вы все еще должны иметь целостность. Но чтобы передать эту информацию наверх, я бы установил переменную экземпляра в объекте, прямо перед тем, как вы вернете false. Поскольку контроллер все еще работает с тем же объектом, что и наблюдатель, эта же информация доступна.

... в вашем Обозревателе model.is_valid = false # or_something_went_wrong = true и т. д. вернуть false

Тогда просто поработайте над этим соответствующим образом в вашем контроллере.

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