Ну, самый (грязный) обходной путь будет примерно таким. Он строит аргументы для preload
на определенную глубину:
def preload_args(relation, max_level \\ 50) do
preload_args(relation, max_level - 1, relation)
end
defp preload_args(_relation, level, acc) when level <= 0, do: acc
defp preload_args(relation, level, acc) do
preload_args(relation, level - 1, [{relation, acc}])
end
Чтобы использовать это:
Repo.preload record, Record.preload_args(:changed_to)
Это будет предварительно загружать каждое :changed_to
отношение к определенному уровню или до тех пор, пока их больше не будет. Конечно, это не то решение, которое вы действительно хотели бы использовать, потому что оно выполняет запрос для каждой предварительной загрузки, и вы не знаете, как долго будет работать цепочка, может быть намного больше, чем 50 шагов.
(пожалуйста, не поджаривайте меня за этот код / предложение, вы специально попросили обходные пути тоже.;)
Я думаю, что этот комментарий о 'закрывающей таблице' от Aetherus, который указал мне на эту статью , вероятно, приведет вас к лучшему решению. Это также усиливает моё предположение, что вам не нужно хранить родительские и дочерние идентификаторы в первую очередь, достаточно одного parent_id. Это также облегчит вставку новой записи: вам также не нужно обновлять родительский элемент.