Не удалось получить внешний ключ во время обратного вызова after_create, потому что он еще не существует! - PullRequest
2 голосов
/ 06 марта 2010

У меня есть несколько моделей, связанных в памяти (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 доступен) и т. д. ?? Если нет, как бы я запустил рутинный пожар после создания записи и получения иностранного ключа?

Кажется, что будет полезен обратный вызов: after_create_with_foreign_keys

Ответы [ 2 ]

2 голосов
/ 03 мая 2010

Поскольку я строил все свои связанные модели в памяти и полагался на Rails для сохранения всего, когда сохранял самого верхнего родителя, я не мог подключиться к обратным вызовам after_create и использовать внешний ключ (для записи таблицы change_log) из-за порядка, в котором Rails будет сохранять модели. Все всегда заканчивалось подключением надлежащим образом, но иногда сначала сохранялась дочерняя запись, затем родительская, а затем происходило обновление дочерней записи для вставки parent_id.

Мое решение состояло в том, чтобы не строить свои модели в памяти, отказавшись от идеи сохранения всего одним махом. Вместо этого я бы сохранил самую верхнюю модель, а затем создал ее потомок через after_create этого родителя. After_create этого потомка создаст его потомок и так далее. Мне эта схема нравится намного лучше, так как у меня больше контроля над обратными вызовами по отношению к внешним ключам. Наконец, все это было заключено в транзакцию базы данных, чтобы отменить любые вставки, если что-то пошло не так по пути. Это была моя первоначальная причина для создания всего в памяти, поэтому перед сохранением я бы собрал всех своих уток подряд. Транзакции модели / дБ снимают беспокойство.

0 голосов
/ 12 марта 2010

Не могли бы вы использовать after_update, чтобы поймать ребенка после того, как parent_id станет доступен? Когда срабатывает after_update, parent_id будет доступен, поэтому, если дочернего элемента нет в таблице, вставьте его.

...