Не удалось получить внешний ключ во время обратного вызова after_create, потому что он еще не существует!
У меня есть несколько моделей, связанных вместе в памяти (parent: child: child: child) и сохраненных одновременно путем сохранения самого верхнего родителя. Это отлично работает.
Я хотел бы подключиться к обратному вызову after_create одного из детей, чтобы заполнить таблицу изменений. Одним из атрибутов, которые мне нужно скопировать / вставить в таблицу изменений, является файл foreign_key дочернего элемента для его прямого родителя, но он не существует в момент запуска after_create!?!
Без обратного вызова after_create я могу посмотреть в журнале и увидеть, что дочерний элемент сохраняется до того, как его родитель (пустой внешний ключ), затем родительский элемент вставляется... затем дочерний элемент обновляется с идентификатором из родительского элемента. Дочерний объект after_create запускается в нужное время, но это происходит до того, как у Rails появится возможность обновить дочерний элемент с помощью foreign_key.
Есть ли способ заставить Rails сохранять такую связь моделей в определенном порядке? ie.parent, затем child (родительский Foreign_key существует), затем дочерний элемент этого дочернего элемента (опять же, Foreign_key доступен) и т. д.?? Если нет, как бы я запустил рутинный пожар после создания записи и получения foreign_key?
Кажется, что будет полезен обратный вызов: after_create_with_foreign_keys
2 ответа
Поскольку я строил все свои связанные модели в памяти и полагался на Rails для сохранения всего, когда сохранял самого верхнего родителя, я не мог подключиться к обратным вызовам after_create и использовать внешний ключ (для записи таблицы change_log) из-за порядок, в котором Rails будет сохранять модели. Все всегда заканчивалось подключением надлежащим образом, но иногда сначала сохранялась дочерняя запись, затем родительская, затем происходило обновление дочерней записи для вставки parent_id.
Мое решение состояло в том, чтобы не строить свои модели в памяти, отказавшись от идеи сохранения всего одним махом. Вместо этого я бы сохранил самую верхнюю модель, а затем создал ее потомок через after_create этого родителя. After_create этого потомка создаст его потомок и так далее. Мне эта схема нравится намного лучше, так как у меня больше контроля над обратными вызовами по отношению к внешним ключам. Наконец, все это было заключено в транзакцию базы данных, чтобы отменить любые вставки, если что-то пошло не так по пути. Это была моя первоначальная причина для создания всего в памяти, поэтому перед сохранением я бы собрал всех своих уток подряд. Транзакции модель / дб смягчают беспокойство.
Не могли бы вы использовать after_update
поймать ребенка после того, как parent_id доступен? когда after_update
срабатывает, parent_id будет доступен, поэтому, если дочерний элемент отсутствует в таблице, вставьте его.