2017-06-16 5 views
4

Je construis une application Web dans Haskell. J'utilise la bibliothèque persistante pour se connecter à une base de données postgresql.Instance ToJSON personnalisée pour clé persistante

J'utilise le système de fichiers de définition de schéma standard dans lequel le modèle Haskell est utilisé pour générer des types à partir du schéma.

share [mkPersist sqlSettings, mkMigrate "migrateAll"] 
    $(persistFileWith lowerCaseSettings "schema") 

J'ai beaucoup de types de données définis dans mon fichier de schéma qui ressemblent (par exemple faux):

User json 
    email Text 

Post json 
    owner UserId 
    name Text 
    body Text 

Le « JSON » à côté de « Post » indique que toJSON/FromJSON doivent être automatiquement généré par le cadre.

J'ai utilisé cette génération automatique d'instance pour plusieurs de mes types afin de pouvoir les sérialiser sur le réseau.

Mon problème: Je souhaite fournir une instance personnalisée de ToJSON pour les clés. Par exemple dans le "UserId" ci-dessus serait un "utilisateur clé". Chaque fois qu'une telle instance est générée automatiquement pour le moment "PostId" comme "Key Post" etc.

Lorsque "Post" est sérialisé, il convertit "owner" d'une clé à l'index comme "52" ".

Je voudrais sérialiser toutes les clés de base de données dans un style différent. Par exemple au lieu de produire le nombre '52' produisant la chaîne "fiftytwo" (juste un exemple).

Si je n'ai pas utilisé la génération de code que je pouvais faire quelque chose comme

instance ToJSON (Key record) where 
    toJSON _ = Data.Aeson.String "placeholder" 

Mais cela nécessiterait de ne pas utiliser la génération automatique de code en raison d'erreurs d'instance qui se chevauchent. Peut-être existe-t-il un moyen de dire au générateur de code de ne pas générer d'instances de "ToJSON (Key Post)" etc pour tous les types de données?

Je pourrais aussi simplement écrire des déclarations d'instance personnalisées pour chaque type mais ce serait très redondant.

Je suis familier avec l'utilisation de newtypes pour avoir plusieurs instances d'une classe de type, mais cela ne rentrerait pas bien dans ce scénario.

Merci!

+1

J'ai aussi rencontré ce problème et malheureusement le paquet 'persistent-th' est très" tout ou rien "à propos des instances Aeson qu'il génère. Sur le grand système de production sur lequel j'ai travaillé, nous avons finalement mordu la balle et fourchu le paquet. Il y a (relativement) pas beaucoup de code. Pour votre problème spécifique, vous pouvez, par exemple, modifier 'mkKeyTypeDec' (où les types de clé sont déclarés puis instanciés) pour produire l'instance' ToJSON' souhaitée. https://hackage.haskell.org/package/persistent-template-2.5.2/docs/src/Database-Persist-TH.html#mpsEntityJSON – hao

Répondre

0

Basé sur le conseil dans le commentaire de haoformayor ce problème est maintenant résolu. La réponse consiste à forker la bibliothèque de modèles persistants et à modifier la partie mkKeyTypeDec.