2015-11-26 55 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"]