Yesod/Persistent one-to-one query

2020-04-12 08:48发布

Say, in Yesod/Persistent, I have models setup like so:

User
    ident Text
    password Text Maybe
    UniqueUser ident
Question
    title Text
    asker UserId Eq

And I have a list of Questions, and would like to retrieve the corresponding list of Users. How would I go about doing this?

I've thought about joins, but those are one-to-many, not one-to-one (I suppose it doesn't matter, but I'd like a simpler solution). Manually doing the join is also an option, but I'm worried about performance - I have

questions <- runDB $ selectList [QuestionTitle !=. ""] [LimitTo 10]
let askerIds = map (\(Entity _ q) -> questionAsker q) questions
askers <- sequence $ map (runDB . get) askerIds
let questionsAndAskers = zip questions askers

but I'm worried about using runDB in the map (wouldn't it make a separate request to the database for each user?)

Is there a better/more idiomatic way to achieve this?

标签: haskell yesod
2条回答
看我几分像从前
2楼-- · 2020-04-12 09:26

I haven't type-checked this yet, but I would stick the whole thing inside of runDB:

runDB $ selectList [QuestionTitle !=. ""] [LimitTo 10] >>= mapM (\qe@(Entity _ q) -> do
    asker <- get $ questionAsker q
    return (qe, asker))
查看更多
【Aperson】
3楼-- · 2020-04-12 09:26

How about:

questions <- runDB $ selectList [QuestionTitle !=. ""] [LimitTo 10]
let askerIds = map (\(Entity _ q) -> questionAsker q) questions
askers <- runDB $ selectList [UserId <-. askerIds] []
let questionsAndAskers = zip questions askers

That seems like it should hit the DB once for the users.

查看更多
登录 后发表回答