我将一些模型全部链接在内存中(parent:child:child:child)并通过保存最顶层的父项同时保存。这很好用。
我想利用其中一个子节点的after_create回调来填充changelog表。我需要复制/推入更改日志表的一个属性是子对它的直接父对象的foreign_key,但是在after_create触发时它不存在!?!
如果没有after_create回调,我可以查看日志并看到孩子在父母(外键空白)之前被保存,然后插入父母......然后孩子更新来自父母的身份证明。孩子的after_create是在正确的时间触发,但它发生在Rails有机会用foreign_key更新孩子之前。
有没有办法强制Rails按特定顺序保存模型的这种链接? ie.parent,那么child(parent foreign_key存在),然后那个孩子的孩子(再次,foreign_key是可访问的)等等?如果没有,在创建记录后如何获取常规火并获取foreign_key?
似乎这样的回调会有所帮助:after_create_with_foreign_keys
答案 0 :(得分:2)
由于我在内存中构建了所有关联模型,并且在保存最顶级父级时依赖Rails保存所有内容,因此无法使用外部密钥并使用外键(对于change_log表条目)因为Rails保存模型的顺序。所有内容总是以正确的方式连接起来,但有时会先保存子记录,然后保存父记录,然后更新子记录以插入parent_id。
我的解决方案是不在内存中构建我的模型,放弃一举保存所有内容的想法。相反,我会保存最顶层的模型,然后通过该父项的after_create创建它的子项。那个孩子的after_create会创建它的孩子,依此类推。我更喜欢这种安排,因为我可以更好地控制与外键相关的回调。最后,整个事情被包装在一个db事务中,以便在一路上出现可怕的错误时撤消任何插入。这是我在内存中构建所有东西的最初原因,所以在保存之前我会把所有的鸭子都连接起来。模型/数据库事务减轻了担忧。
答案 1 :(得分:0)
在parent_id可用后,您可以使用after_update
来抓住孩子吗?当after_update
触发时,parent_id将可用,因此如果子表不在表中,则插入它。