我正在尝试将我的应用程序从phoenix 1.2更新到1.3。
在我的频道中,handle_in
个函数之一获得order_id
和food_id
来创建OrderItem
changeset = order
|> build_assoc(:order_items)
|> Myapp.OrderItem.changeset(%{food_id: food.id,
price: food.price,
quantity: 1,
order_id: order.id,
created_date: time_now})
case Repo.insert(changeset) do
{:ok, order_item} ->
max_rounds = Repo.one!(from p in Myapp.OrderItem, where: p.order_id == ^order.id, select: max(p.round))
Myapp.Order.changeset(order, %{total: order.total + (order_item.price * order_item.quantity), rounds: max_rounds}) |> Repo.insert_or_update
end
所以上面的代码来自phoenix 1.2版本的应用程序,它的作用是当用户成功创建order_item
时,它会更新order
。它工作正常。
with {:ok, %OrderItem{} = order_item} <- Myapp.create_order_item(%{food_id: food.id,
price: food.price,
order_id: order.id,
created_date: time_now}) do
max_rounds = Repo.one!(from p in OrderItem, where: p.restaurant_order_id == ^order.id, select: max(p.round))
Myapp.update_order(order, %{total: order.total + (order_item.price * order_item.quantity), rounds: max_rounds})
end
Phoenix 1.3引入了model
的新用法,因此我从create_order_item
调用Myapp
函数Myapp.Order
和Myapp.OrderItem
来创建order_item
。
def create_order_item(attrs \\ %{}) do
%OrderItem{}
|> order_item_changeset(attrs)
|> Repo.insert()
end
即使我传递了我需要插入数据库的所有字段,它也不会插入数据库。我该如何解决?我在这里做错了什么?
提前致谢。
---修改
def create_order_item(attrs \\ %{}) do
time_now = Ecto.DateTime.cast!
(:calendar.universal_time_to_local_time(:calendar.universal_time()))
%OrderItem{created_date: time_now}
|> order_item_changeset(attrs)
|> Repo.insert()
end
答案 0 :(得分:1)
您的字段的类型为utc_datetime
,但您已将Ecto.DateTime
传递给它,但无法将其转换为utc_datetime
:
iex(1)> Ecto.Type.cast(:utc_datetime, Ecto.DateTime.utc())
:error
相反,您可以直接传递:calendar.universal_time_to_local_time/1
返回的Erlang日期时间元组:
time_now = :calendar.universal_time_to_local_time(:calendar.universal_time())
您也可以使用与上述相同的:calendar.local_time()
:
time_now = :calendar.local_time()
另外,你真的应该在使用with
时处理失败的情况,否则错误的情况将被忽略,就像它在这里一样,直到我们在评论中找到它:
with {:ok, %OrderItem{} = order_item} <- Myapp.create_order_item(...) do
...
else
{:error, error} ->
# handle error
end