2017-08-12 13 views
1

私はtsrange columnのPostgresテーブルを持っています。私はEctoモジュールのschemaにそれを含めたいと思います。私はそれがPostgrex.Range existsを参照してください。私はこの試みた:tsrangeフィールドを持つEctoスキーマ

schema "clients" do 
    field :valid_at, Postgrex.Range 
    ... 
end 

をしかし、それは私にこのエラー与える:

** (ArgumentError) invalid or unknown type Postgrex.Range for field :valid_at 
    lib/ecto/schema.ex:1785: Ecto.Schema.check_type!/3 
    lib/ecto/schema.ex:1473: Ecto.Schema.__field__/4 

任意の提案を?私はPhoenix 1.3とEcto masterブランチを使用しています。

答えて

0

@TheAnhは正しいアプローチを持っているが、ここでは実際のために働いて巻き取るものですように見えます私:

defmodule Myapp.TsRange do 
    @behaviour Ecto.Type 

    def type, do: :tsrange 

    def cast(nil),   do: {:ok, nil} 
    def cast([lower, upper]), do: {:ok, [lower, upper]} 
    def cast(_),    do: :error 

    def load(%Postgrex.Range{lower: lower, upper: upper}) do 
    lower = lower |> to_datetime 
    upper = upper |> to_datetime 
    case [lower, upper] do 
     [nil, nil]     -> {:ok, [nil, nil]} 
     [{:ok, lower}, {:ok, upper}] -> {:ok, [lower, upper]} 
     _ -> :error 
    end 
    end 
    def load(_), do: :error 

    def dump([lower, upper]) do 
    {:ok, %Postgrex.Range{lower: lower |> from_datetime, 
          upper: upper |> from_datetime, 
          upper_inclusive: false}} 
    end 
    def dump(_), do: :error 

    defp to_datetime(nil), do: nil 
    defp to_datetime({{y, m, d}, {h, min, s, ms}}) do 
    NaiveDateTime.new(y, m, d, h, min, s, ms) 
    end 

    defp from_datetime(nil), do: nil 
    defp from_datetime(dt) do 
    {{dt.year, dt.month, dt.day}, {dt.hour, dt.minute, dt.second, elem(dt.microsecond, 0)}} 
    end 

end 
3

Ectoを使用するには、tsrangeのカスタムタイプを作成する必要があります。包括的境界について

defmodule YourApp.TimestampRange do 
@behaviour Ecto.Type 

    def type, do: :tsrange 

    def cast([lower, upper]) do 
    {:ok, [lower, upper]} 
    end 

    def cast(_), do: :error 

    def load(%Postgrex.Range{lower: lower, upper: upper}) do 
    {:ok, [lower, upper]} 
    end 

    def dump([lower, upper]) do 
    {:ok, %Postgrex.Range{lower: lower, upper: upper, upper_inclusive: false}} 
    end 

    def dump(_), do: :error 
end 

チェックアウトPostgreSQL documentation

、その後、あなたのアプリケーションで使用することができます:

schema "clients" do 
    field :valid_at, YourApp.TimestampRange 
    ... 
end 
+1

ここで最初の 'load'節は本当に必要ありません。 2番目の節は、 'nil'ケースをまったく同じように扱います。 – Dogbert

+0

ああ、ありがとう! – TheAnh

関連する問題