凤凰城 1.3 使用通道插入数据



我正在尝试将我的应用程序从 phoenix 1.2 更新到 1.3。

在我的频道中,handle_in函数之一order_idfood_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 版本的 app,它的作用是当用户成功创建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的新用法,所以我从Myapp调用create_order_item函数,该函数具有Myapp.OrderMyapp.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

您的字段具有类型utc_datetime,但您正在向其传递一个无法转换为utc_datetimeEcto.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

最新更新