I'm trying to use Yesod and persistent to create a website. I'm a bit confused about how to use the persistent API.
Here's two of my tables
Feed
url Text
UniqueFeed url
Subscription
feed FeedId
title Text
UniqueSubscription feed
I'm trying to create a Feed if a feed with that URL does not exists, and then add a subscription to that feed, if a subscription does not already exist.
postFeedR :: Handler RepHtml
postFeedR = do
url <- runInputPost $ ireq urlField "url"
title <- runInputPost $ ireq textField "title"
runDB $ do
feedId <- insertFeed $ UniqueFeed url
subscriptionId <- insertSubscription feedId title
return
defaultLayout [whamlet| <p>done|]
insertFeed url = do
f <- insertBy $ UniqueFeed url
case f of
Left (Entity uid _) -> uid
Right (Key uid) -> do
(Key uid) <- insert $ Feed url
return uid
insertSubscription feedId title = do
s <- insertBy $ UniqueSubscription feedId
case s of
Left (Entity uid _) -> uid
Right (Key uid) -> do
(Key uid) <- insert $ Subscription feedId title
return uid
I get the errors below. I don't understand why ghc thinks that the return value of insertFeed and insertSubscription should be UniqueFeed and UniqueSubscription. I would like those functions to return the keys of the newly created records.
Also, it seems like I'm throwing away the Key that I get back in each of the Right clauses of the case. Why does persistent return those keys. In the case where the UniqueSubscription is not in the database, persistent does not have enough information to create a new Subscription record, because it is missing the title, which is not on the UniqueSubscription.
If someone could give me some pointers on how to use the persistent API, I would really appreciate it.
Handler/Home.hs:62:9:
Kind incompatibility when matching types:
a0 :: *
GHandler App App :: * -> *
Expected type: (a0 -> t0)
-> (t0 -> a0 -> m0 a0) -> YesodDB App App (m0 a0)
Actual type: (a0 -> t0) -> (t0 -> a0 -> m0 a0) -> a0 -> m0 a0
In a stmt of a 'do' block: feedId <- insertFeed $ UniqueFeed url
In the second argument of `($)', namely
`do { feedId <- insertFeed $ UniqueFeed url;
subscriptionId <- insertSubscription feedId title;
return }'
Handler/Home.hs:62:9:
Couldn't match type `YesodPersistBackend App' with `(->)'
Expected type: (a0 -> t0)
-> (t0 -> a0 -> m0 a0) -> YesodDB App App (m0 a0)
Actual type: (a0 -> t0) -> (t0 -> a0 -> m0 a0) -> a0 -> m0 a0
In a stmt of a 'do' block: feedId <- insertFeed $ UniqueFeed url
In the second argument of `($)', namely
`do { feedId <- insertFeed $ UniqueFeed url;
subscriptionId <- insertSubscription feedId title;
return }'
Handler/Home.hs:74:20:
Couldn't match expected type `Unique Feed'
with actual type `Database.Persist.Store.PersistValue'
In the first argument of `return', namely `uid'
In a stmt of a 'do' block: return uid
In the expression:
do { (Key uid) <- insert $ Feed url;
return uid }
Handler/Home.hs:83:20:
Couldn't match expected type `Unique Subscription'
with actual type `Database.Persist.Store.PersistValue'
In the first argument of `return', namely `uid'
In a stmt of a 'do' block: return uid
In the expression:
do { (Key uid) <- insert $ Subscription feedId title;
return uid }
insertBy doesn't take a Unique constraint as parameter, getBy is more appropriate.
But insertUnique is a short possibility with Maybe result.
postFeedR :: Handler RepHtml
postFeedR = do
url <- runInputPost $ ireq urlField "url"
title <- runInputPost $ ireq textField "title"
runDB $ do
feedId <- insertFeed url
_mbSubscriptionId <- insertUnique $ Subscription feedId title
return ()
defaultLayout ...
insertFeed url = do
f <- insertBy $ Feed url
case f of
Left (Entity uid _) -> return uid
Right uid -> return uid
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With