Question

Each element in a list will trigger some DB updates but I keep getting stuck with the return type. Could you please let me know what's the correct way to do this?

for ::  [a] -> (a -> b) -> [b]
for xs f = map f xs

-- Summary: Loop over the elements of xs and update the table for each element
-- get an ID from the element
-- get the record corresponding to that ID
-- extract more values
-- update table (below is just a dummy updateWhere 
-- but the above values will be used in the update eventually )
forM_ xs $ \(Entity xid val) -> do
            let qid = tableField val 
            y <- runDB $ get404 qid
            let z = table2Field y
            return $ updateWhere [PersonName ==. "Test"] [PersonAge *=. 1] 

I get the following error:

Couldn't match type `PersistMonadBackend m0'
               with `persistent-1.2.1:Database.Persist.Sql.Types.SqlBackend'
Expected type: PersistMonadBackend m0
  Actual type: PersistEntityBackend Person
In the second argument of `($)', namely
  `updateWhere [PersonName ==. name] [PersonAge *=. 1]'

I tried using for instead of forM or forM_ and it does not fix anything. At this point, I am just trying a whole bunch of combinations without really understanding how to fix this error. Appreciate your help!

Update:

Here is the actual code that I am working with. When I get rid of most of the let statements and just run updateWhere with a trivial update it still gives me the same error.

getCalculateDeltaR :: personId -> Handler Html
getCalculateDeltaR personId = do

    goods <- runDB $ selectList [GoodPerson ==. personId] [] 

    forM goods $ \(Entity gid good) -> do
                let aid = goodAsset good  
                asset <- runDB $ get404 aid
                let mktValue = assetMktValue asset
                return $ updateWhere [GoodPerson ==. personId, GoodAsset = aid] [GoodDelta =. (mktValue - GoodOrigValue)]  

    defaultLayout $ do
        $(widgetFile "calculateDelta")

If I change the forM above to:

    forM goods $ \(Entity gid good) -> do
                return $ updateWhere [GoodPerson ==. personId] [GoodDelta =. 1]  

I still get the same error about mismatched types.

Was it helpful?

Solution

I'm not very familar with yesod, but I think the following code should work:

forM_ xs $ \(Entity xid val) -> do
        let qid = tableField val 
        y <- runDB $ get404 qid
        let z = table2Field y
        runDB $ updateWhere [PersonName ==. "Test"] [PersonAge *=. 1] 

You don't want to return DB Actions and then throw them away (forM_ throws the individual return values away), because that would just result in no action. You have to run them.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top