Обратный вызов after_save модели act_as_nested_set приводит к SystemStackError

Я использую Рельсы 5.1.6

У меня есть модель под названием Taxon с использованием acts_as_nested_set. У меня есть 4 уровня таксонов, последний уровень sub_category имеет атрибут, содержащий имена всех родителей, я хочу обновлять атрибут sub_category каждый раз, когда изменяется имя любого из его родителей, при использовании обратного вызова after_save он сталкивается с SystemStackError как каждый после обратного вызова сохранения запускается для каждого потомка, что приводит к бесконечному циклу. Любая идея, как преодолеть эту проблему?

class Taxon
  acts_as_nested_set dependent: :destroy

  def update_tree_name
  if shop_sub_category?
    update(display_tree_name: beautiful_name)
  else 
    related_sub_categories = tree_list.select{ |taxon| taxon.kind == "sub_category" }
    related_sub_categories.each do |t|
      t.update(display_tree_name: t.beautiful_name)
    end
  end
end


def beautiful_name
  "#{parent.parent.parent.name} -> #{parent.parent.name} -> #{parent.name}-> #{name}"
end

person Selim Alawwa    schedule 11.11.2018    source источник


Ответы (1)


У меня есть решение, которое подойдет вам, но я не думаю, что оно элегантное, но вот, пожалуйста, и тогда вы сможете его настроить:

В вашей модели:

class Taxon < ActiveRecord::Base
  cattr_accessor :skip_callbacks
  after_save :update_tree_name, :unless => :skip_callbacks
end

def update_tree_name
  if shop_sub_category?
    update(display_tree_name: beautiful_name)
  else 
    related_sub_categories = tree_list.select{ |taxon| taxon.kind == "sub_category" }
    Taxon.skip_callbacks = true # disable the after_save callback so that you do not end up in infinite loop (stackoverflow)
    related_sub_categories.each do |t|
      t.update(display_tree_name: t.beautiful_name)
    end
    Taxon.skip_callbacks = false # enable callbacks again when you finish
  end
end
person Tarek N. Elsamni    schedule 11.11.2018
comment
Спасибо, это помогает! - person Selim Alawwa; 11.11.2018