Phoenix 1.3使用频道插入数据

时间:2017-05-07 07:29:08

标签: elixir phoenix-framework

我正在尝试将我的应用程序从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版本的应用程序,它的作用是当用户成功创建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.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

1 个答案:

答案 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