## 6.5.4 Flow Scopes

#### Scope Basics

You'll notice from previous examples that we used a special object called `flow` to store objects within "flow scope". Grails flows have 5 different scopes you can utilize:

- `request` - Stores an object for the scope of the current request
- `flash` - Stores the object for the current and next request only
- `flow` - Stores objects for the scope of the flow, removing them when the flow reaches an end state
- `conversation` - Stores objects for the scope of the conversation including the root flow and nested subflows
- `session` - Stores objects inside the users session

> Grails service classes can be automatically scoped to a web flow scope. See the documentation on Services for more information.

Also returning a model map from an action will automatically result in the model being placed in flow scope. For example, using a transition action, you can place objects within `flow` scope as follows:

    enterPersonalDetails {
       on("submit") {
             [person:new Person(params)]
       }.to "enterShipping"
       on("return").to "showCart"
    }

Be aware that a new request is always created for each state, so an object placed in request scope in an action state (for example) will not be available in a subsequent view state. Use one of the other scopes to pass objects from one state to another. Also note that Web Flow:

1. Moves objects from flash scope to request scope upon transition between states;
2. Merges objects from the flow and conversation scopes into the view model before rendering (so you shouldn't include a scope prefix when referencing these objects within a view, e.g. GSP pages).

#### Flow Scopes and Serialization

When placing objects in `flash`, `flow` or `conversation` scope they must implement `java.io.Serializable` otherwise you will get an error. This has an impact on domain classes in that domain classes are typically placed within a scope so that they can be rendered in a view. For example consider the following domain class:

    class Book {
    	String title
    }

In order to place an instance of the `Book` class in a flow scope you will need to modify it as follows:

    class Book implements Serializable {
    	String title
    }

This also impacts associations and closures you declare within a domain class. For example consider this:

    class Book implements Serializable {
    	String title
    	Author author
    }

Here if the `Author` association is not `Serializable` you will also get an error. This also impacts closures used in GORM events such as `onLoad`, `onSave` and so on. The following domain class will cause an error if an instance is placed in a flow scope:

    class Book implements Serializable {
    	String title
    	def onLoad = {
    		println "I'm loading"
    	}
    }

The reason is that the assigned block on the `onLoad` event cannot be serialized. To get around this you should declare all events as `transient`:

    class Book implements Serializable {
    	String title
    	transient onLoad = {
    		println "I'm loading"
    	}
    }