Как получить связанные данные, используя внешний ключ - PullRequest
0 голосов
/ 04 июня 2019

Я пытаюсь написать функцию, которая ищет профиль пользователя или создает его, если он не существует.

Я использовал getBy и selectFirst, чтобы получить профиль данного пользователя, но я получаю эту ошибку:

Не удалось сопоставить тип «Обработчик для сайта 0» с «Ключом»

Я использую сайт строительных лесов с 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 ]

1 голос
/ 04 июня 2019

Если вы посмотрите на подпись типа runDB :

runDB :: YesodDB site a -> HandlerFor site a

вы увидите, в чем проблема.

Yesod требует от вас сделать довольно сложные вещи, чтобы реально использовать результаты запроса - это не просто (может быть, результат). Вы можете найти примеры здесь ; эта часть в частности:

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

Надеюсь, это поможет.

0 голосов
/ 05 июня 2019

Это компиляция

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
...