Reputation: 5417
I'm trying to insert an Ecto model in the table worklogs
which has two relationships user_id
and issue_id
. I find that when I try to create a changeset for a worklog with valid integers for these two fields, they are not included in the changeset and are null in the resulting worklog
and API response. I've made sure that a user
and issue
exists with the primary keys I'm inserting with the worklog
.
I've also looked at the documentation and it seems like build_assoc/3
is the way to update relationships, but it seems to be limited to inserting for a single relationship. From the docs, I think I should do something like this:
user = #get the user
worklog = Ecto.build_assoc(user, :worklogs, worklog_params)
But I've never declared worklogs
on user
, so how does it know to set user_id
on the worklog? Also, how do I subsequently add the issue_id
?
Schemas:
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
Controller logic:
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 request:
{
"worklog": {
"start_time": "2017-04-08 02:20:00",
"end_time": "2017-04-08 02:30:00",
"issue_id": 1,
"user_id": 1
}
}
Upvotes: 0
Views: 572
Reputation: 4507
Need to see your changeset to provide a concrete answer. However, I suspect your missing user_id
and issue_id
in the cast
call in your changeset. Ecto will not add fields to the changes if the fields are not listed in the cast list.
The phoenix model generator does not add belongs_to fields to the cast operation. I usually add them manually.
Upvotes: 1
Reputation: 10041
In this case of multiple relations needing to be set, it is probably better to just set them explicitly like this
%Worklog{user_id: user.id, issue_id: issue.id}
|> Worklog.changset(worklog_params)
|> Repo.insert()
You may also benefit from putting relations onto your user and issue schemas so that you are able to easier query for the worklogs that relate to a given user or issue.
Upvotes: 1