haskellhaskell-persistent

Insert entity into DB with manually created foreign key in Persistent library (Haskell)


I have the following entities defined with Persistent library:

ClapEntity
    Id Text
    count Int
    userId UserEntityId
    deriving Show
UserEntity
    Id Text
    name Text
    email Text
    deriving Show

I want to store new ClapEntity from ClapCreate data model:

newtype UserId = UserId {unUserId :: UUID}
  deriving (Eq, Show, ToJSON, FromJSON)

data ClapCreate = ClapCreate
  { userId :: UserId,
    count :: Int
  }
  deriving (Eq, Show)

-- Insert a new clap record into the database
storeClap :: ConnectionPool -> ClapCreate -> IO ClapId
storeClap pool clap = do
  let clapEntity = clapCreateToEntity clap
  key <- generateClapEntityKey
  cid <- runSql (insertKey key clapEntity) pool
  case toUUID (unClapEntityKey key) of
    Left err -> error $ show err
    Right uuid -> return $ ClapId uuid

clapCreateToEntity :: ClapCreate -> ClapEntity
clapCreateToEntity (ClapCreate (UserId uid) cnt) =
  ClapEntity
    cnt
    (UserEntityId (UUID.toText uid)) -- ISSUE HERE

I don't know how to create a new UserEntityId from given uid :(

Also, I don't want to fetch the UserEntity first and use returned key, just want to create a new foreign key. I am missing something...

Bonus question

Btw, how can I use cid in case toUUID (unClapEntityKey key) of line?


Solution

  • You refer to an object α with αKey, so in this case UserEntityKey:

    clapCreateToEntity :: ClapCreate -> ClapEntity
    clapCreateToEntity (ClapCreate (UserId uid) cnt) =
      ClapEntity
        cnt
        (UserEntityKey (UUID.toText uid))

    The UserEntityId also exists, but this is a data constructor without any parameters: it is used to refer to a column in an expression, like selectList [UserEntityId ==. "c86aed00-023a-4368-89ce-56e5cbcd810e"]