9

According to http://www.yesodweb.com/blog/2010/07/database-migrations a DeleteCascade typeclass was added a few years ago. I can only assume that this is meant to be added to the models. After setting up my models config like this:

Field
    ...
    foreignId ForeignId DeleteCascade

my application compiles fine. but the DB schema is unchanged, and the delete is not cascaded by the application either. Should I just (shudder) do it manually? Is there a better way?

I'm using the Yesod scaffold (Application.hs, Foundation.hs, Settings.hs, ...)

CharlesB
  • 86,532
  • 28
  • 194
  • 218
abesto
  • 2,331
  • 16
  • 28

2 Answers2

12

Using the existing answers, it took some time for me to figure out how to use the delete cascade. As a beginner in Yesod, I did not have an overview over Yesod.

To get a working delete cascade you don't need to change anything in the model. Let's say your entities file looks like the following and you want to delete the Entry.

Entry
    title Text
Comment
    entry EntryId

You do not have to change this entity file.

The code from where you lead the entities, typically in Model.hs, looks like that.

share [ mkPersist sqlOnlySettings
      , mkMigrate "migrateAll" ]
    $(persistFileWith lowerCaseSettings "config/models")

Add the mkDeleteCascade to get the DeleteCascades instances for your entities.

share [ mkPersist sqlOnlySettings
      , mkDeleteCascade sqlOnlySettings
      , mkMigrate "migrateAll" ]
    $(persistFileWith lowerCaseSettings "config/models")

Once you want to delete your entry, for example in the postDeleteEntryR Handler you have to use deleteCascade or deleteCascadeWhere instead of delete.

runDB $ deleteCascade entryId

Using delete has the same effect as before.

Bastian Holst
  • 136
  • 1
  • 4
4

In order to take advantage of DeleteCascade, you need to use either the deleteCascade or deleteCascadeWhere functions. These will only work if there are DeleteCascade instances available for your types. The easiest way to get these is with the mkDeleteCascade function.

Michael Snoyman
  • 31,100
  • 3
  • 48
  • 77
  • Thanks for the answer so far. Could you expand a bit? My problem: http://hackage.haskell.org/packages/archive/persistent-template/1.0.0/doc/html/Database-Persist-TH.html says that regular users shouldn't need to use mkDeleteCascade. http://hackage.haskell.org/packages/archive/persistent/1.0.0/doc/html/src/Database-Persist-Query-Internal.html says that deleteCascadeWhere is for internal use only. I also can't find any useful docs on deleteCascade. Could you show / point me to a minimal working example of this? – abesto Sep 16 '12 at 10:08
  • The comments about internal use or regular users weren't applied to the functions themselves, but to the modules. Those modules you link to are both re-exported by other modules (e.g., Yesod.Persist). There's no problem with using those functions. Unfortunately I don't have a complete example, however. – Michael Snoyman Sep 16 '12 at 10:56