2013-04-30 14 views
6

私はYesodを使用して永続的にウェブサイトを作成しようとしています。私は永続的なAPIの使い方について少し混乱しています。Haskell永続的な挿入行がデータベースにまだない場合

は、ここに私のテーブルの二つが

Feed 
    url Text 
    UniqueFeed url 

Subscription 
    feed FeedId 
    title Text 
    UniqueSubscription feed 

私は、サブスクリプションが存在しない場合は、そのURLでフィードが存在しない場合はフィードを作成し、そのフィードにサブスクリプションを追加しようとしています。

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 

下記のエラーが発生します。私はghcがなぜinsertFeedとinsertSubscriptionの戻り値がUniqueFeedとUniqueSubscriptionでなければならないと思うのか分かりません。これらの関数は、新しく作成されたレコードのキーを返すようにしたいと思います。

また、ケースの右句のそれぞれに戻る鍵を捨てているようです。なぜ永続的にそれらのキーを返すのですか? UniqueSubscriptionがデータベースにない場合、UniqueSubscriptionにないタイトルがないため、永続的に新しいサブスクリプションレコードを作成するのに十分な情報がありません。

永続的なAPIの使い方を教えていただけたら、本当にありがとう。

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 } 
+0

「insertBy $ Feed url」を使用してください。 –

答えて

7

insertBygetByがより適切である、パラメータとしてユニーク制約を負いません。

ただし、 insertUnique は、おそらく結果が短い可能性があります。

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 
関連する問題