代码之家  ›  专栏  ›  技术社区  ›  jvans

在snap中使用持久数据类型的类型安全路由

  •  2
  • jvans  · 技术社区  · 9 年前

    我有一个Snap应用程序使用Persistent进行存储,我正在尝试为Persistent中定义的数据类型生成类型安全路由。我正在使用 snap-web-routes package :.

    我有以下TemplateHaskell函数,它创建 Group GroupId :

    share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
      Group
        name T.Text
        deriving Show
    |]
    

    在我的 Application.hs 我有:

    data AppUrl = AddLink GroupId deriving (Eq, Show, Read, Generic)
    

    医生建议:

    instance PathInfo AppUrl
    

    考虑到 Generic 上面的推导,但是这会导致

    No instance for (PathInfo (KeyBackend SqlBackend Group))
          arising from a use of ‘Web.Routes.PathInfo.$gdmtoPathSegments’
    

    我的假设是,这个错误表明Haskell不知道如何使用Persistent的数据类型自动创建实例定义。

    我的下一次尝试是手动定义实例:

    instance PathInfo AppUrl where
      toPathSegments   (AddLink groupId) = "add-link" : toPathPiece groupId : []
      fromPathSegments (x:y:[]) = ????
    

    我似乎不知道如何构造 组ID 数据类型。

    来自Yesod的优秀 Persistent tutorial 我知道数据类型定义为:

    type GroupId = Key Group
    newtype Key Group = GroupKey (BackendKey SqlBackend)
    

    但后来我遇到了一个问题,因为 BackendKey 未公开,因此我无法导入它并创建自己的实例。我似乎找不到在Persistent中创建此数据类型的公共API。

    1 回复  |  直到 9 年前
        1
  •  1
  •   Cactus    9 年前

    The documentation for SqlBackend 显示关联的数据类型 BackendKey 已为安装 SQL后端

    data BackendKey SqlBackend = SqlBackendKey {
        unSqlBackendKey :: Int64
    }
    

    这应该是足够你自己写的信息 PathInfo 例如,沿着以下示例的线:

    {-# LANGUAGE TypeFamilies #-}
    
    import Database.Persist.Sql
    import Data.Int (Int64)
    
    foo :: BackendKey SqlBackend -> Int64
    foo (SqlBackendKey key) = key
    
    bar :: Int64 -> BackendKey SqlBackend
    bar = SqlBackendKey