Ecto预加载嵌套

Ecto preload nested

我正在学习 phoenix 和 ecto 关联,但我在尝试预加载嵌套关联时偶然发现了一个我似乎无法解决的问题。我有 3 个模式

具有

的优惠
schema "offers" do
    ...
    has_one :albumMariageSmall, Album, on_delete: :delete_all, on_replace: :delete
    has_one :prewedding, Prewedding, on_delete: :delete_all, 
    on_replace: :delete
    has_one :next_day, Prewedding, on_delete: :delete_all, on_replace: :delete
end

现在,婚前的样子

schema "preweddings" do
    ...
    has_one :album, Album, on_delete: :delete_all, on_replace: :delete
end

专辑看起来像

schema "albums" do
    ...
    belongs_to :offer, Offer
    belongs_to :prewedding, Prewedding
end

换句话说,一个offer可以有一个Album和两个Prewedding,其中Prewedding可以有一个Album。

数据库方面,:preweddings 通过 offer_id 引用报价,:albums 通过 offer_id 引用报价,通过 prewedding_id.

引用婚前报价

我在加载任何保存的报价时遇到问题,因为 :prewedding 和 :next_day 在我检查时似乎指向同一行。

我正在尝试使用

预加载
offer=Repo.one from(o in Offer, preload: [{:prewedding, [:album]},{:next_day, [:album]}], select: o, where: o.id==^id)

我想我可以让它与连接一起工作,但我很固执,想要做预加载。

有人可以帮忙吗?

婚前移民就是这样

add :included, :boolean, default: false, null: false
add :offer_id, references(:offers)

相册有

add :offer_id, references(:offers)
add :prewedding_id, references(:preweddings)

默认情况下,当使用 has_one 时,外键是从当前 table 的名称推断出来的,例如offers -> offer_id。由于您有两个 has_one 并且您没有为其中任何一个指定自定义外键,因此两者都将使用 offer_id 作为外键,因此将始终具有相同的值。您需要为两个 has_one 指定正确的外键。例如,如果您的 preweddings table 有此迁移:

add :offer_prewedding_id, references(:offers)
add :offer_next_day_id, references(:offers)

您需要做的:

has_one :prewedding, Prewedding, on_delete: :delete_all, on_replace: :delete, foreign_key: :offer_prewedding_id
has_one :next_day, Prewedding, on_delete: :delete_all, on_replace: :delete, foreign_key: :offer_next_day_id