2015-11-26 16 views
2

我使用结构在Phoenix/Elixir应用程序中创建自定义模型。像这样:协议枚举没有为struct实现。如何将结构转换为可枚举?

defmodule MyApp.User do 
    defstruct username: nil, email: nil, password: nil, hashed_password: nil 
end 

new_user = %MyApp.User{email: "[email protected]", hashed_password: nil, password: "secret", username: "ole"} 

为了使用它与我的数据库适配器,我需要的数据是可枚举的。哪一个结构显然不是。至少我收到这个错误:

(Protocol.UndefinedError) protocol Enumerable not implemented for %MyApp.User{ ... 

所以我试着用理解力来运气。这当然也不起作用,因为结构是不可枚举(愚蠢的我)

enumberable_user = for {key, val} <- new_user, into: %{}, do: {key, val} 

我怎样才能将数据转换为可枚举的地图?

回答

3

您可以使用Map.from_struct/1在插入到数据库的位置转换为映射。这将删除__struct__密钥。

您曾经能够派生Enumerable协议,但它似乎是偶然的。 https://github.com/elixir-lang/elixir/issues/3821

Ouch, it was an accident that deriving worked before, I don't think we should fix it. Maybe we could update the v1.1 changelog to make it clear but I wouldn't do a code change.

defmodule User do 
    @derive [Enumerable] 
    defstruct name: "", age: 0 
end 

Enum.each %User{name: "jose"}, fn {k, v} -> 
    IO.puts "Got #{k}: #{v}" 
end 
0

我创建的模块make_enumerable解决这一问题:

defmodule Bar do 
    use MakeEnumerable 
    defstruct foo: "a", baz: 10 
end 

iex> import Bar 
iex> Enum.map(%Bar{}, fn({k, v}) -> {k, v} end) 
[baz: 10, foo: "a"]