SystemStackError пытается вызвать `.to_yaml` в объекте сиквела

Я начал работать в старом проекте, и если я попытаюсь найти запись сиквела, а затем преобразовать ее в yaml:

fj = FullJob.find(1)
fj.to_yaml

Я получаю stack level too deep ошибка. Проверка глубже, есть @record_collection переменная экземпляра, определенная в записи сиквела, которая приносит копию того же объекта, а внутри него еще одну копию того же самого и так далее...:

[7] pry(main)> fj.instance_variables
=> [:@record_collection, :@cequel_attributes, :@collection_proxies, :@loaded, :@persisted]
[8] pry(main)> fj.instance_variable_get(:@record_collection)
=> [#<FullJob id: 1, #...
[9] pry(main)> fj.instance_variable_get(:@record_collection).first.instance_variable_get(:@record_collection)
=> [#<FullJob id: 1, #...

Проблема в том, что в какой-то момент анализатор ruby ​​yaml пытается проанализировать все переменные экземпляра объекта, которые в конечном итоге выводятся в упомянутом SystemStackError,
Стоит отметить, что это происходит только в этой конкретной модели, я имею в виду, насколько я видел, @record_collection переменная приходит nil для другой модели сиквела, представленной в этом проекте.
Совершенно не уверен, как это работает, если это ошибка сиквела или что-то не правильно настроено в модели, но... может быть, это связано с ленивой загрузкой сиквела?, в любом случае у меня кончаются идеи:(

1 ответ

Стоит отметить, что это происходит только в этой конкретной модели

На самом деле это не так. Я думаю, что это происходит с любой записью, которую сначала лениво создавали как "выгруженную", а затем загружали позже - ее @record_collection остается там даже после загрузки (по крайней мере, я легко воспроизвел ту же ошибку).

Я не могу найти ни одного места в cequel исходный код, где они сбрасывают значение переменной этого экземпляра (это не происходит при загрузке наверняка). С другой стороны, кажется, что это значение не используется где-либо еще, кроме этого ленивого поведения загрузки (так что оно становится "бесполезным" после загрузки записи), так что может быть безопасно использовать такой уродливый помощник по исправлению ошибок, как

def cequel_to_yaml(record)
  record.load unless record.loaded?
  record.instance_variable_set(:@record_collection, nil)
  record.to_yaml
end
Другие вопросы по тегам