2016-09-24 3 views
10

normalizrを使用してエンティティの親に関連するid/slugを割り当てるにはどうしたらいいですか?Normalizr - 親エンティティに関連するslug/idの生成方法

例:私は次のように私のスキーマを定義することができ

{ 
    id: '12345', 
    firstName: 'John', 
    images: [ 
    { 
     url: 'https://www.domain.com/image0', 
     name: 'image0' 
    }, 
    { 
     url: 'https://www.domain.com/image1', 
     name: 'image1' 
    } 
    ] 
} 

:ユーザー・コールのための

APIレスポンス

const image = new Schema('images'); 
const user = new Schema('users'); 

user.define({ 
    images: arrayOf(image) 
}) 

問題は、画像が持っていないということですidプロパティであるため、idプロパティを指定しない限り、normalizrはそれらを区別できません。もちろん、

const image = new Schema('images', { idAttribute: uuid.v4() }); 

のようなものを実行して、一意の識別子を生成することができます。

ユーザーの更新を受け取り、イメージの名前が更新されたとします。すべての正規化で一意の識別子を生成するため、既存のイメージを識別して更新することはできません。

私はどちらかのID /スラグ中12345-image012345-image1または別のプロパティなどのような(画像エンティティに親エンティティ(ユーザー)を参照する方法が必要です。

これを達成するための最適な方法だろう何?

答えて

1

idAttributeエンティティ、親と状態のスライスを参照するキーを受け取る関数とすることができる。

const image = new Schema('images', { 
    idAttribute: (entity, parent) => `${parent.id}-${entity.name}` 
}); 
2

問題

あなたが表示する方法はうまくいかないでしょう。

const image = new Schema('images', { idAttribute: uuid.v4() }); 

uuid.v4()文字列、idAttributeの許容値を返しますが、今、すべてのあなたのimagesは同じUIDを持つことになります。あなたが望むものではありません。

理想的には、これは動作します:in this issueが述べたように

const image = new Schema('images', { idAttribute:() => uuid.v4() }); 

を残念ながら、idAttributeは、複数回呼び出されます。これにより、エンティティリレーションが破棄されます。あなたの例では、イメージはユーザーエンティティがそれらを参照するものとは異なるuidを持ちます。

出力例:

users: { 
    '12345': { 
    id: '12345', 
    firstName: 'John', 
    images: [ 
     "cj20qq7zl00053j5ws9enz4w6", 
     "cj20q44vj00053j5wauawlr4u" 
    ], 
    } 
}; 
images: { 
    cj20q44v100003j5wglj6c5h8: { 
    url: 'https://www.example.org/image0', 
    name: 'image0' 
    }, 
    cj20q44vg00013j5whajs12ed: { 
    url: 'https://www.example.org/image1', 
    name: 'image1' 
    } 
}; 

ソリューション

周りにこの作業はそれをuid属性を与え、processStrategyコールバックで入力値を変異させることです。

const getUid = value => { 
    if (!Object.prototype.hasOwnProperty.call(value, 'uid')) value.uid = uuid.v4(); 
    return {...value}; 
}; 

const image = new Schema('images', { processStrategy: getUid, idAttribute: 'uid'}); 

あなたは今値を変異しているので、それは吸うが、idAttributeオプションは、入力値ではなく、処理された値を使用しています。

また、idAttributeコールバックの値を変更すると、uidフィールドが出力値に追加されません。

追記:私はuuid

+0

の代わりにcuid NPMパッケージを使用することをお勧めします 'processStrategy'を使用すると、idフィールドに新しいオブジェクトを返すことができ、値を変異させる必要はありません。 – nathancahill

+0

'idAttribute'パラメータは返されたオブジェクトを参照していないので、元の' value'を参照します。それが私が元の価値を変えなければならなかった理由です。 (私が間違っていない限り、これを数回チェックしてみると思いますが、私もpaul armstrongで確認しました) –

+1

正しいかもしれません、 'getId'関数は' processedEntity'ではなく、元の 'input'を参照しています:https: //github.com/paularmstrong/normalizr/blob/a20d535c0ddd21c95cf8498647fa8e060b5ed8a8/src/schemas/Entity.js#L61 – nathancahill

関連する問題