2016-08-23 2 views
2

私はエリクサー/フェニックスを学ぶのに役立つおもちゃプロジェクトを持っています。エリクシルのカスタムタイプ

私はcsvからいくつかのデータをインポートしています。これらのレコードが私のチェンジセットに従って有効であれば、そのレコードをデータベースに挿入したいと思います。

私が持っている質問は、通常、整数を含む列の1つに「n/a」があることがあるということです。これにより、チェンジセットは無効になります。

これを処理するための標準的なエリクシルの方法はわかりません。

これらのケースでは、私はちょうど「N /」0

に変換するあなたは、通常、その変換を行い、このためのカスタム型を記述しますをしたいですか?

https://hexdocs.pm/ecto/Ecto.Type.html

Railsでは、私は、カスタムセッターを使用してモデルやbefore_saveか何かでこれを解決する可能性があります。

答えて

4

モデルのchangeset機能では、を「修正」することで、検証のためにcastに送信されます。 :count整数フィールドを持つ

例モデル:

def changeset(struct, params \\ %{}) do 
    struct 
    |> cast(fix_params(params), [:count]) 
    |> validate_required([:count]) 
end 

defp fix_params(%{count: "n/a"} = params), do: %{params | count: 0} 
defp fix_params(params), do: params 

デモ:あなたは任意の非整数値が0に変換したい場合は

iex(1)> Counter.changeset(%Counter{}, %{count: 123}) 
#Ecto.Changeset<action: nil, changes: %{count: 123}, errors: [], 
data: #MyApp.Counter<>, valid?: true> 
iex(2)> Counter.changeset(%Counter{}, %{count: "n/a"}) 
#Ecto.Changeset<action: nil, changes: %{count: 0}, errors: [], 
data: #MyApp.Counter<>, valid?: true> 
iex(3)> Counter.changeset(%Counter{}, %{count: "foo"}) 
#Ecto.Changeset<action: nil, changes: %{}, 
errors: [count: {"is invalid", [type: :integer]}], data: #MyApp.Counter<>, 
valid?: false> 

は、あなたが行うことができます。

defp fix_params(%{count: count} = params) when not is_integer(count), do: %{params | count: 0} 
defp fix_params(params), do: params 

デモ:

iex(1)> Counter.changeset(%Counter{}, %{count: "foo"}) 
#Ecto.Changeset<action: nil, changes: %{count: 0}, errors: [], 
data: #MyApp.Counter<>, valid?: true> 
+0

ありがとう@Dogbert!カスタムタイプを使用する良い例がたくさんあるわけではありません。これはトップのヒットhttp://learningelixir.joekain.com/custom-types-in-ecto/です。私はカスタムタイプと "クリーナー"機能を使用するという決定は、あなたが何をする必要があるのか​​複雑になると思いますか? – jacklin

関連する問題