【问题标题】:Custom ToJSON instance for Persistent Key持久键的自定义 ToJSON 实例
【发布时间】:2017-11-19 03:33:42
【问题描述】:

我正在用 Haskell 构建一个 Web 应用程序。我正在使用持久库连接到 postgresql 数据库。

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

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

我的架构文件中定义了许多数据类型,看起来像(假示例):

User json
  email Text

Post json
  owner UserId
  name  Text
  body  Text

“Post”旁边的“json”表示ToJSON/FromJSON由框架自动生成。

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

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

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

我想将所有数据库键序列化为不同的样式。例如,不是生成数字“52”而是生成字符串“fiftytwo”(只是一个示例)。

如果我不使用代码生成,我可以做类似的事情

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

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

我也可以简单地为每种类型编写自定义实例声明,但这将是非常多余的。

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

谢谢!

【问题讨论】:

  • 我也遇到过这个问题,不幸的是,persistent-th 包对它生成的 Aeson 实例非常“全有或全无”。在我工作的大型生产系统上,我们最终硬着头皮分叉了软件包。 (相对)没有那么多代码。例如,对于您的特定问题,您可以修改 mkKeyTypeDec(其中声明键类型然后实例化)以生成所需的 ToJSON 实例。 hackage.haskell.org/package/persistent-template-2.5.2/docs/src/…

标签: haskell yesod aeson haskell-persistent


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多