2013-05-27 12 views
6

Se abbiamo definito 2 semplici oggetti nel nostro file modelli, ad esempio: -Come definire un campo su un modulo applicativo per una chiave esterna in Yesod?

Person 
    name Text 
    Age Int 
Book 
    title Text 
    author Text 

Possiamo definire un modulo applicativo per Book come: -

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

Tuttavia, se vogliamo cambiare l'autore da solo un campo di testo, per l'id di una persona, come: -

Book 
    title Text 
    author PersonId 

Poi il modulo di cui sopra non si compila, con questo errore: -

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' 

Come definiamo ora il campo autore? Abbiamo bisogno di usare una forma monadica?

Grazie!

risposta

6

Il messaggio di errore indica che si sta tentando di utilizzare Testo (dal risultato del campo) come chiave.

È possibile utilizzare checkMMap per avvolgere il textField e modificare il risultato:

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) 

La funzione findAuthor diventa più semplice se si aggiunge un costruttore unico al campo Persona:

Person 
    name Text 
    ... 
    UniquePerson name 

Allora, invece di selectFirst ... si può fare

mperson <- runDB $ getBy $ UniquePerson name 
Problemi correlati