4

假设我有两个 Ecto 模型(以及它们的迁移):

schema "projects" do
    field :name, :string

    belongs_to :client, MyApp.Client

    timestamps
end

create table(:projects) do
      add :name, :string
      add :client_id, references(:clients)

      timestamps
end

schema "clients" do
    field :name, :string

    has_many :projects, MyApp.Project

   timestamps
end

create table(:clients) do
  add :name, :string

  timestamps
end

如果我查询了一个项目模型,例如。

project = Repo.get!(Project, proj.id)

正如预期的那样,我无法访问project.client.id,因为我没有preload在查询中使用 a 。

每当我尝试访问project.client_id它时,它都会返回 nil。当然,我应该能够访问外键 ID 本身吗?

希望下面的代码能更好地说明:

client = Repo.insert!(%Client{name: "Test Client"})
proj = Repo.insert!(%Project{name: "Test Project 1", client: client})

project = Repo.get!(Project, proj.id)
assert project.client_id != nil
# ^ This always fails because project.client_id is nil
4

3 回答 3

3

这里的问题是您构建的方式proj导致该client_id字段永远不会被填充。您可以通过签入数据库来验证这一点。

您可以使用Ecto.Model.build/3从客户端创建项目:

proj = build(client, :projects, %{name: "Test Project 1"}) |> Repo.insert!
于 2015-09-29T12:08:22.460 回答
0

尝试直接设置字段(正如有人已经提到的那样):

proj = Repo.insert!(%Project{name: "Test Project 1", client_id: client.id})
于 2015-09-29T21:33:30.313 回答
0

另一种方法是直接在项目上设置客户端的 id。

client = Repo.insert!(%Client{name: "Test Client"})
proj = Repo.insert!(%Project{name: "Test Project 1", client_id: client.id})

当您更新 :client_id 时,存储在 :client 中的关联会自动更新,因为 Ecto 知道这两者是相关的。

于 2018-08-14T00:09:17.577 回答