Ecto 模型更新多个关系

Ecto model update multiple relationships

我试图在 table worklogs 中插入一个 Ecto 模型,它有两个关系 user_idissue_id。我发现当我尝试为这两个字段使用有效整数的工作日志创建变更集时,它们不包含在变更集中并且在结果 worklog 和 API 响应中为空。我已确保 userissue 与我使用 worklog.

插入的主键一起存在

我也看了文档,似乎build_assoc/3是更新关系的方式,但它似乎仅限于插入单个关系。从文档中,我认为我应该这样做:

user = #get the user
worklog = Ecto.build_assoc(user, :worklogs, worklog_params)

但我从未在 user 上声明过 worklogs,那么它怎么知道要在工作日志上设置 user_id?另外,我如何随后添加 issue_id?

模式:

  schema "worklogs" do
    field :start_time, Ecto.DateTime
    field :end_time, Ecto.DateTime
    belongs_to :issue, MyApi.Issue
    belongs_to :user, MyApi.User

    timestamps()
  end

  schema "users" do
    field :name, :string

    timestamps()
  end

  schema "issues" do
    field :title, :string
    field :status, :string
    field :description, :string
    field :estimate, :float

    timestamps()
  end

控制器逻辑:

def create(conn, %{"worklog" => worklog_params}) do
    changeset = Worklog.changeset(%Worklog{}, worklog_params)

    IO.inspect changeset #user_id and issue_id are not present

    case Repo.insert(changeset) do
      {:ok, worklog} ->
        conn
        |> put_status(:created)
        |> put_resp_header("location", worklog_path(conn, :show, worklog))
        |> render("show.json", worklog: worklog)
      {:error, changeset} ->
        conn
        |> put_status(:unprocessable_entity)
        |> render(MyApi.ChangesetView, "error.json", changeset: changeset)
    end
  end

POST 请求:

{
  "worklog": {
    "start_time": "2017-04-08 02:20:00",
    "end_time": "2017-04-08 02:30:00",
    "issue_id": 1,
    "user_id": 1
  }
}

在这种需要设置多个关系的情况下,最好像这样显式设置它们

%Worklog{user_id: user.id, issue_id: issue.id}
|> Worklog.changset(worklog_params)
|> Repo.insert()

您还可能受益于将关系置于您的用户和问题模式中,以便您能够更轻松地查询与给定用户或问题相关的工作日志。

需要查看您的变更集才能提供具体答案。但是,我怀疑您在变更集中的 cast 调用中缺少 user_idissue_id。如果字段未在演员列表中列出,则 Ecto 不会将字段添加到更改中。

phoenix 模型生成器不会将 belongs_to 字段添加到转换操作中。我通常手动添加它们。