4

I am building a web application in Haskell. I am using the persistent library to connect to a postgresql database.

I am using the standard schema definition file system where template Haskell is used to generate types from the schema.

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

I have many data types defined in my schema file that look like (fake example):

User json
  email Text

Post json
  owner UserId
  name  Text
  body  Text

The "json" next to "Post" indicates that ToJSON / FromJSON are to be automatically generated by the framework.

I have been using this automatic instance generation for many of my types so that I can serialize them over the network.

My issue: I want to provide a custom instance of ToJSON for the Keys. For example in the above "UserId" would be a "Key User". Every time has such an instance generated for it automatically at the moment "PostId" as "Key Post" etc.

When "Post" is serialized it would convert "owner" from a key to the index number like say "52".

I would like to serialize all of the database keys to a different style. For example instead of producing the number '52' producing the string "fiftytwo" (just an example).

If I did not use code generation I could do something like

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

But this would require not using the automatic code generation because of overlapping instance errors. Perhaps there is a way to tell the code generator not to generate instances of "ToJSON (Key Post)" etc for all the datatypes?

I could also simply write custom instance declarations for every type but this would be very redundant.

I am familiar with using newtypes to have multiple instances of a type class, however this would not fit well into this scenario.

Thanks!

Harpo
  • 81
  • 3
  • 1
    I too have run into this problem and unfortunately the `persistent-th` package is very "all or nothing" about the Aeson instances it generates. On the large production system I worked on, we eventually bit the bullet and forked the package. There is (relatively) not that much code. For your specific problem you could, for example, modify `mkKeyTypeDec` (where the key types are declared and then instanced) to produce the desired `ToJSON` instance. https://hackage.haskell.org/package/persistent-template-2.5.2/docs/src/Database-Persist-TH.html#mpsEntityJSON – hao Jun 20 '17 at 15:14

1 Answers1

0

Based by the advice in the comment from haoformayor this issue is now solved. The answer is to fork the persistent-template library and modify the mkKeyTypeDec portion.

Harpo
  • 81
  • 3