Почему SystemStackError вызывается ассоциацией has_many в Ruby on Rails? - PullRequest
1 голос
/ 06 апреля 2011

Я наткнулся на ошибку SystemStackError и обнаружил, где она вызывается в исходном коде. Хотя я не совсем понял, почему это происходит. Может быть, вы можете помочь мне.

Вот сценарий:
Существуют две модели Facility и Location, заданные в следующих определениях моделей.

class Location < ActiveRecord::Base
  belongs_to :facility
  accepts_nested_attributes_for :facility
end

class Facility < ActiveRecord::Base
  has_many :locations
  accepts_nested_attributes_for :locations
end

Теперь я создаю объект каждого класса в консоли Rails: rails c.

location = Location.create(...)
facility = Facility.create(...)

Тогда я хочу связать оба друг с другом.

location.facility = facility
facility.locations << location

Я не могу выполнить последнюю команду, когда выполнил первую ранее - она ​​вызывает SystemStackError: stack level too deep. Хотя я могу запускать команды ассоциации отдельно или последовательно, но в обратном порядке. Проблема в том, что я не могу добавить location снова. Почему?

Ответы [ 2 ]

1 голос
/ 06 апреля 2011

Почему оба?

Эта строка:

facility.locations << location

Уже установит объект местоположения равным указанному facility.Обе строки в этом случае делают одно и то же.Я бы порекомендовал использовать построитель ассоциаций, например так:

facility.locations.create!(...)

Таким образом, Rails позаботится о настройке поля facility_id, а не о том, чтобы вы выполняли ручное назначение после него.

1 голос
/ 06 апреля 2011

Первое, что я подозреваю, это то, что ассоциация has_many действительно имеет has_too_many. Другими словами, у вас может быть слишком много местоположений в отношениях.

На самом деле, учитывая код, который вы разместили, вы, кажется, создали бесконечный цикл ассоциаций. Вы написали:

accepts_nested_attributes_for :facility

Я предполагаю, что это заставляет ActiveRecord открыть атрибут объекта, где он находит другое местоположение с еще одним атрибутом объекта до бесконечности. прежде чем копать слишком глубоко, попробуйте это, чтобы увидеть, работает ли оно:

facility.locations << location
location.facility = facility

Однако, будьте осторожны, потому что это может привести к ошибке стека в другом месте приложения. Если вы отправите Google это сообщение об ошибке, вы можете найти нескольких людей, которые столкнулись с бесконечной рекурсией, обычно связанной с сохранением записи.

...