如何使用外键获取关联数据

时间:2019-06-04 04:24:53

标签: haskell yesod one-to-one persistent

我正在尝试编写一种寻找用户个人资料的功能,或者创建一个不存在的个人资料。

我已经使用getBy和selectFirst来获取给定用户的个人资料,但出现此错误:

无法将类型“ HandlerFor site0”与“密钥”匹配

我正在使用带有postgres的脚手架站点。

这是我的模型(用户和个人资料具有一对一关系)

User
    email Text
    password Text Maybe
    verkey Text Maybe
    verified Bool
    UniqueUser email                                                                                                   
    deriving Typeable

Profile 
    name Text                                                                                                          
    userId UserId
    UniqueName name
    UniqueUserId userId
    deriving Typeable

功能如下:

getOrCreateProfile :: UserId -> ProfileId
getOrCreateProfile userId = do
    mProfile <- runDB $ getBy $ UniqueUserId userId                                                                    
    case mProfile of
        Just (Entity pid _) -> return pid
        Nothing  -> undefined -- insert profile

我得到的错误是:

    • Couldn't match type ‘HandlerFor site0’ with ‘Key’
      Expected type: Key (Maybe (Entity Profile))
        Actual type: HandlerFor site0 (Maybe (Entity Profile))
    • In a stmt of a 'do' block:
        mProfile <- runDB $ getBy $ UniqueUserId userId
      In the expression:
        do mProfile <- runDB $ getBy $ UniqueUserId userId
           case mProfile of
             Just (Entity pid _) -> pid
             Nothing -> undefined
      In an equation for ‘getOrCreateProfile’:
          getOrCreateProfile userId
            = do mProfile <- runDB $ getBy $ UniqueUserId userId
                 case mProfile of
                   Just (Entity pid _) -> pid
                   Nothing -> undefined
   |
45 |     mProfile <- runDB $ getBy $ UniqueUserId userId
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

我在做什么错?进行此查询的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

如果您查看runDB's type signature

runDB :: YesodDB site a -> HandlerFor site a

您会看到问题所在。

是的,Yesod要求您做一些相当复杂的事情才能实际使用查询的结果-这不仅仅是(可能是结果)。您可以找到示例here;特别是这部分:

people <- runDB $ selectList [] [Asc PersonAge]
defaultLayout
        [whamlet|
            <ul>
                $forall Entity personid person <- people
                    <li>
                        <a href=@{PersonR personid}>#{personFirstName person}
        |]

希望这会有所帮助。

答案 1 :(得分:0)

正在编译

getOrCreateProfile :: UserId -> Handler ProfileId
getOrCreateProfile userId = runDB $ do
    mProfile <- getBy $ UniqueUserId userId
    case mProfile of
        Just (Entity pid _) -> return pid
        Nothing  -> insert $ Profile getTempProfile userId