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

Итак, в основном, когда вы создаете сообщение:

  1. Сохраняет сообщение

  2. Вызовы process обратный вызов (after_create_commit)

  3. Вызовы re_process (потому что это называется в process метод при выполнении save!)

  4. Вызовы process еще раз (потому что это называется re_process)

  5. И так далее...

Этот цикл вызывает Stack level to deep

Надеюсь, это помогло!

Другие вопросы по тегам