Ecto 去除预紧力

lap*_*ira 5 elixir ecto

有什么办法可以逆向预加载吗?

%Post{
  comments: []
}

posts = Repo.all(Post) |> Repo.unload(:comments)

%Post{
  comments: #Ecto.Association.NotLoaded<association :comments is not loaded>,
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*kin 7

Ecto.Association.NotLoaded是一个普通的简单结构,因此您可能相对容易地自己实现unpreload

defmodule Unpreloader do
  def forget(struct, field, cardinality \\ :one) do
    %{struct | 
      field => %Ecto.Association.NotLoaded{
        __field__: field,
        __owner__: struct.__struct__,
        __cardinality__: cardinality
      }
    }
  end
end
Run Code Online (Sandbox Code Playgroud)

稍后将其用作:

Unpreloader.forget(%Post{....}, :comments)
Run Code Online (Sandbox Code Playgroud)

  • 嘿,这对测试来说很酷,当你用 ex_machine 做 insert() &amp; build(:assoc),然后与 `Item.get!()` 的结果进行比较时 (2认同)

Dog*_*ert 5

回答评论中的实际问题:

问题是我在测试中收到一个已经预加载关联的对象,并且我想使用一个未预加载关联的库来测试它,并且如果只有其中一个预加载了注释,我无法断言 post1 == post2

如果其他一切都相同,我只需在断言之前删除该字段:

assert Map.delete(post1, :comments) == Map.delete(post2, :comments)
Run Code Online (Sandbox Code Playgroud)

或者如果您想删除多个字段:

fields = [:comments, :users]
assert Map.drop(post1, fields) == Map.drop(post2, fields)
Run Code Online (Sandbox Code Playgroud)