Rails: before_save - уровень стека слишком глубокий
У меня есть эта простая модель:
class Post < ApplicationRecord
after_create_commit :process
before_save :re_process, on: :update
has_one :processed, class_name: 'Post::Process'
def process
self.processed.destroy if self.processed
processed = self.build_processed
processed.save!
end
private
def re_process
self.process if self.title_changed?
end
end
Я получаю Stack level to deep
ошибка каждый раз, когда я создаю новый Post
,
Теперь, когда я удаляю before_save :re_process, on: :update
все отлично работает
Разве эта строка не должна влиять, только когда я обновляю сообщение?
2 ответа
on: :update or on: :create
не работает для before_save
Для этого вы должны использовать before_update
class Post < ApplicationRecord
after_create_commit :process
before_update :re_process
has_one :processed, class_name: 'Post::Process'
def process
self.processed.destroy if self.processed
processed = self.build_processed
processed.save!
end
private
def re_process
self.process if self.title_changed?
end
end
Если вы используете on
вариант с before_save
обратный вызов будет выполнен независимо от того, что указано в on
вариант.
Надеюсь это поможет
Да, добавленный вами ранее update
работает нормально
Проблема в том, что у вас есть after_create_commit
который код сохраняет запись после того, как она уже была создана.
def process
# here the Post was already created
self.processed.destroy if self.processed
processed = self.build_processed
processed.save! # And here, you are updating the Post, so it triggers the re_process
end
Итак, в основном, когда вы создаете сообщение:
Сохраняет сообщение
Вызовы
process
обратный вызов (after_create_commit)Вызовы
re_process
(потому что это называется вprocess
метод при выполненииsave!
)Вызовы
process
еще раз (потому что это называетсяre_process
)И так далее...
Этот цикл вызывает Stack level to deep
Надеюсь, это помогло!