古いモデル状態を新しいモデル状態に移行することは非常に困難です。ModelV1型からModelV2型に変換するJsonデコーダを書く方法
最初にコードにModelがあり、それをlocalstorageに保存したとします。
ここで、追加のフィールド「createdAt」をモデルに追加したいので、同じタイプの新しいタイプエイリアスを作成しました。 V1/V2形式のJSON文字列のいずれかを受け入れ、私にModelV2
レコードを与えること、デコーダ/関数を記述する方法
import Json.Decode as D
import Html as H
type alias Todo = {id:Int, title: String}
jsonV1 = """
{"id":1, "title":"Elm-Rocks"}
"""
jsonV2 = """
{"id":1, "title":"Elm-Rocks", "createdAt":1479633701604}
"""
type alias TodoV2 = {id:Int, title: String, createdAt:Int}
decode = D.map2 Todo
(D.field "id" D.int)
(D.field "title" D.string)
decodeV2 = D.map3 TodoV2
(D.field "id" D.int)
(D.field "title" D.string)
(D.field "createdAt" D.int)
result1 = D.decodeString decode jsonV1
result2 = D.decodeString decodeV2 jsonV2
type alias Model = {todos: List Todo}
type alias ModelV2 = {todos: List TodoV2}
main = H.div[] [
H.div[][H.text (toString result1)]
, H.div[][H.text (toString result2)]
]
。
私はDecoder.andThenの承知していますが、私はあなたが新しいフィールドをオプションに場合は、単一のモデルを使用することができますtodoDecoderV1: ??? -> TodoV2
私は「不可能な状態」の話をしていましたが、まだ完了していません。 しかし、createdAtはオプションのフィールドではないので、私は多分コード全体にチェックを入れたくありません。スキーマが変わるたびに、私はおそらく使用していることを示唆していますか?それは対処するのに大変なことです。新しいコードは、有効なcreate atを生成することを保証します。このデコードは、スキーマの移行中にのみ行われます。 – Jigar
これは分かります。あなたがそのルートに行くことを選択した場合、あなたは賢明なデフォルトを必要とします。最初の 'oneOf'の例ではゼロを使用しましたが、ビジネスに必要なものは何でも使用できます。 –