Ecto 模型更新多个关系
Ecto model update multiple relationships
我试图在 table worklogs
中插入一个 Ecto 模型,它有两个关系 user_id
和 issue_id
。我发现当我尝试为这两个字段使用有效整数的工作日志创建变更集时,它们不包含在变更集中并且在结果 worklog
和 API 响应中为空。我已确保 user
和 issue
与我使用 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_id
和 issue_id
。如果字段未在演员列表中列出,则 Ecto 不会将字段添加到更改中。
phoenix 模型生成器不会将 belongs_to 字段添加到转换操作中。我通常手动添加它们。
我试图在 table worklogs
中插入一个 Ecto 模型,它有两个关系 user_id
和 issue_id
。我发现当我尝试为这两个字段使用有效整数的工作日志创建变更集时,它们不包含在变更集中并且在结果 worklog
和 API 响应中为空。我已确保 user
和 issue
与我使用 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_id
和 issue_id
。如果字段未在演员列表中列出,则 Ecto 不会将字段添加到更改中。
phoenix 模型生成器不会将 belongs_to 字段添加到转换操作中。我通常手动添加它们。