如何解决协议可枚举未实现 {:ok, ["Massimo Dutti", "Sneakers laag", "38", "Black", "99.95"]} 类型元组
对于学校项目,我们必须在 elixir 中创建一个可以通过上传 csv 文件来创建新产品的网上商店。我们尝试通过遵循 How to import users from csv file with elixir/phoenix? 来实现这一点,但我们总是得到一个错误(见标题)
有人可以帮助我们吗?这是我们的代码:
表格
<%= form_for @changeset,@action,[multipart: true],fn f -> %>
<div class="form-group">
<label>File</label>
<%= file_input f,:file,class: "form-control" %>
</div>
<div class="form-group">
<%= submit "Submit",class: "btn btn-primary" %>
</div>
<% end %>
渲染
<%= render "bulkform.html",changeset: @changeset,action: Routes.product_path(@conn,:createBulk) %>
路线
post "/productsBulk",ProductController,:createBulk
架构
schema "products" do
field :color,:string
field :size,:string
field :description,:string
field :price,:decimal
field :title,:string
timestamps()
end
@doc false
def changeset(product,attrs) do
product
|> cast(attrs,[:title,:description,:size,:color,:price,:stock])
|> validate_required([:title,:stock])
|> unique_constraint(:title,name: :unique_products_index,message:
"Title already in use.")
end
控制器
def createBulk(conn,%{"product" => product_params}) do
product_params["file"].path
|> File.stream!()
|> CSV.decode
|> Enum.each(fn(product) -> Product.changeset(%Product{},%{title: Enum.at(product,0),description:
Enum.at(product,1),size: Enum.at(product,2),color: Enum.at(product,3),price: Enum.at(product,4)})
|> Repo.insert() end)
conn
|> put_flash(:info,"Imported")
|> redirect(to: Routes.product_path(conn,:overview))
end
解决方法
如果您完整地包含错误消息,并且您能准确地向我们显示错误消息中提到的行,那将会更有帮助。
但是,正如 Aleksei 已经指出的那样,我怀疑您的问题是您将 元组 传递给 Enum.each/1
,而您应该传递一个列表。换句话说:
Enum.each({:ok,[1,2,3]},fn x -> IO.puts(x) end)
** (Protocol.UndefinedError) protocol Enumerable not implemented for ...
虽然这很好用:
Enum.each([1,3],fn x -> IO.puts(x) end)
因此 CSV.decode
的输出不能直接传送到 Enum
函数中,因为它返回一个元组,但使用 CSV.decode!
应该返回原始列表,您的代码应该可以工作。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。