Yesod persistent: get Entity value inside village

let's say my config / models file looks like this:

Pet
    name Text
    owner OwnerId
Owner
    name Text

      

I can get the name of a pet like this:

 $forall Entity key pet <- pets
     <span>#{petName pet} 

      

but how can I get the owner name from the pet object?

In other words, what should foo

be the following:

 <span>#{ownerName $ foo $ petOwner pet}

      

+3


source to share


1 answer


Yesod doesn't create functions for relationships in the way that it can (like rails), so you just have to write this thing yourself.

-- just one naive example
petOwnerName :: Pet -> Handler (Maybe Text)
petOwnerName p = do
    mo <- runDB $ get (petOwner p)
    return $ fmap ownerName mo

      

Note that this returns in the handler (and it must be related to the DB query), which means you couldn't use it directly as foo

in interpolation.



Taking your example literally, doing this from a template is exactly what you expect from it. I would like to emphasize that this is usually a design smell, and I would recommend that you restructure things so that you do all your db requests before the handler in the handler and then pass any (clean) values ​​the template needs directly to it. You could build and transfer to [(Pet,Owner)]

or [(Owner, [Pet])]

for example.

I have a couple of helpers on one of my sites that abstract the common ways to query the DB for one-to-many relationships and return a list of tuples like (parent, child)

. I find this to be the most useful method.

Hope it helps.

+4


source







All Articles