使用Elixir,Ecto.Query,Postgres
我通过联接表User
在Location
和UserLocation
之间建立了关联。我使用deleted_at
作为软删除,并在查询时检查is_nil(ul.deleted_at)
如果我软删除连接表记录,我将
%User{id: 1, name: "larskris", deleted_at: nil, location: #Ecto.Association.NotLoaded<association :location is not loaded>}
%UserLocation{id: 25, user_id: 1, location_id: 13, deleted_at: #DateTime<2018-01-17 18:01:45Z>}
%Location{id: 13, address: "Some street", deleted_at: nil}
如何运行Ecto查询以阻止这些&#34;已删除&#34;地点?
Repo.one(
from u in User,
left_join: ul in UserLocation, on: a.id == ul.activity_id and is_nil(ul.deleted_at),
left_join: l in Location, on: ul.location_id == l.id and is_nil(l.deleted_at),
where: u.id == ^user_id
and is_nil(u.deleted_at),
preload: [:location]
)
以上内容返回用户,但也预先加载了应为零的位置。即使没有相关位置,我也总是想要用户。
到目前为止我尝试的所有内容都会预先加载软删除的位置
单独查询位置和用户,然后将其映射以构建我需要的工作但不理想 使用内置关联还会返回软删除的位置。
答案 0 :(得分:1)
使用preload
来使用LEFT JOIN可能只是一个问题(我认为你给定的语法会自行完成一个全新的预加载)。
from u in User,
left_join: ul in UserLocation, on: a.id == ul.activity_id and is_nil(ul.deleted_at),
left_join: l in Location, on: ul.location_id == l.id and is_nil(l.deleted_at),
where: u.id == ^user_id and is_nil(u.deleted_at),
preload: [location: l]
有关详细信息,请参阅Ecto docs for preload()。