2013-05-27 13 views
6

我々は例えば、私たちのモデルファイルで2つの単純なオブジェクトを定義した場合: -Yesodの外部キー用の申請フォームにフィールドを定義する方法は?

Person 
    name Text 
    Age Int 
Book 
    title Text 
    author Text 

我々はブックのための応用的フォームを定義することができますように: -

addBookForm = renderDivs $ Book 
    <$> areq textField "title" Nothing 
    <*> areq textField "author" Nothing 

しかし

、我々は変更したい場合だけでテキストフィールドから、人のIDへの著者、: -

Book 
    title Text 
    author PersonId 

その後、上記のフォームは、このエラーで、コンパイルされません: -

Couldn't match expected type `KeyBackend Database.Persist.GenericSql.Raw.SqlBackend Person' with actual type `Text' 
Expected type: Field 
       sub0 
       master0 
       (KeyBackend Database.Persist.GenericSql.Raw.SqlBackend Person) 
    Actual type: Field sub0 master0 Text 
In the first argument of `areq', namely `textField' 
In the second argument of `(<*>)', namely 
    `areq textField "author" Nothing' 

どのように我々は今、著者のフィールドを定義していますか? モナド形式を使用する必要がありますか?

ありがとうございます!

答えて

6

エラーメッセージは、フィールド結果からのテキストをキーとして使用しようとしていることを意味します。

あなたはTextFieldをラップし、その結果を修正するためにcheckMMapを使用することができます:あなたは人のフィールドに独自のコンストラクタを追加した場合

addBookForm = renderDivs $ Book 
    <$> areq textField "title" Nothing 
    <*> (entityKey <$> areq authorField "author" Nothing) 
    where 
    authorField = checkMMap findAuthor (personName . entityVal) textField 

    findAuthor name = do 
    mperson <- runDB $ selectFirst [PersonName ==. name] [] 
    case mperson of 
     Just person -> return $ Right person 
     Nothing  -> return $ Left ("Person not found." :: Text) 

findAuthor機能はシンプルな取得します。

Person 
    name Text 
    ... 
    UniquePerson name 

その後の代わりに、あなたが行うことができますselectFirst ...

mperson <- runDB $ getBy $ UniquePerson name 
関連する問題