У меня есть модель базы данных с парой таблиц, которые выглядят так:
date value_1 value_2 value_3
----------------------------------
-infinity 5 6 7
12-01-2012 4 6 7
15-01-2012 4 7 8
16-01-2012 7 7 8
В приложении данные (в основном) используются как отдельные значения;важны различные значения в столбцах:
date value_1 date value_2 date value_3
------------------ ------------------ ------------------
-infinity 5 -infinity 6 -infinity 7
12-01-2012 4 15-01-2012 7 15-01-2012 8
16-01-2012 7
Этот дизайн вызывает некоторые проблемы: я не могу просто «вставить», «обновить» и «удалить» некоторое значение для value_2
псевдо-таблицы, так какможет повлиять на значения в других столбцах: если я удаляю value_2
для 15-01-2012, удаление всей записи изменит как value_2
, так и value_3
псевдо-таблицу.
Очевидное решениедля этой проблемы (для меня) является использование обратных вызовов для улучшения действий создания, обновления и уничтожения с правильным поведением, используя обратные вызовы * 1013. * Я создал класс для этих обратных вызовов:
class TemporalCallbacks
def self.around_destroy(record)
# modify the record: replace it with the values from the previous entry
...
# do an update instead of the destroy
record.save
record.logger.debug "end of destroy callback"
end
def self.around_update(record)
...
end
end
class SomeModel < ActiveRecord::Base
...
around_update TemporalCallbacks
around_destroy TemporalCallbacks
...
end
Используя этот метод, мой контроллер может быть очень чистым, поскольку бизнес-логика ничего не знает об этой модели базы данных. Мои модели также могут быть чистыми, поскольку обратные вызовы могут использоваться на нескольких моделях. Контроллер:
class SomeController < ApplicationController
def destroy
@some_model = SomeModel.find(params[:id])
@some_model.destroy
logger.debug "destroyed!"
# respond to the end user
...
end
end
К сожалению, транзакция откатывается после обратного вызова around_destroy, как показано в журналах:
... some successful sql update queries
end of destroy callback
(0.2ms) ROLLBACK
destroyed!
Я пытался очистить обратный вызов around_destroy,но это приводит к тому же поведению: откат срабатывает, где-то после обратного вызова around_destroy.
Почему этот откат срабатывает и как я могу это исправить?
Я действительно хочу решить этот дизайнпроблема с использованием обратных вызовов: это сэкономило бы много работы, если бы мне не пришлось создавать обновление вместо взлома во всех моих моделях / контроллерах.Как я могу решить это?