2017-06-16 36 views
4

我正在Haskell中构建一个Web应用程序。我正在使用持久库来连接到postgresql数据库。Persistent Key的自定义ToJSON实例

我正在使用标准模式定义文件系统,其中模板Haskell用于从模式生成类型。

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

我有一个看起来像我的架构文件中定义很多数据类型(假的例子):

User json 
    email Text 

Post json 
    owner UserId 
    name Text 
    body Text 

的“JSON”旁边的“邮报”指出的toJSON/FromJSON是自动由框架生成。

我一直在使用这种自动实例生成许多我的类型,以便我可以通过网络序列化它们。

我的问题:我想为Keys提供一个ToJSON的自定义实例。例如在上面的“UserId”将是一个“关键用户”。每次在“PostId”时刻自动生成这样的实例为“Key Post”等。

当“Post”被序列化时,它会将“owner”从键转换为索引号,如“52” ”。

我想序列化所有的数据库键到不同的风格。例如,不是生成产生字符串“fiftytwo”的数字“52”(只是一个例子)。

如果我没有使用代码生成我可以做类似

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

但是这需要不使用,因为重叠的实例错误的代码自动生成。也许有办法告诉代码生成器不要为所有数据类型生成“ToJSON(Key Post)”等实例吗?

我也可以简单地为每个类型编写自定义实例声明,但这会非常冗余。

我很熟悉使用newtypes有一个类型的多个实例,但是这不适合这种情况。

谢谢!

+1

我也遇到过这个问题,不幸的是,'persistent-th'软件包对于它生成的Aeson实例非常“无所谓”。在我工作的大型生产系统上,我们终于找到了子弹并将其包装起来。有(相对)不太多的代码。例如,对于你的具体问题,你可以修改'mkKeyTypeDec'(其中的键类型被声明,然后实例化)来产生所需的ToJSON实例。 https://hackage.haskell.org/package/persistent-template-2.5.2/docs/src/Database-Persist-TH.html#mpsEntityJSON – hao

回答

0

根据来自haoformayor的评论中的建议,现在已解决此问题。答案是分叉持久模板库并修改mkKeyTypeDec部分。