js/libs/ember-data.js
function(object) {
  // Ignore internal property defined by simulated `Ember.create`.
  var names = Ember.keys(object);
  var i, l, name;
  for (i = 0, l = names.length; i < l; i++ ) {
    name = names[i];
    if (object.hasOwnProperty(name) && object[name]) { return true; }
  }

  return false;
}
function(object) {
  // Ignore internal property defined by simulated `Ember.create`.
  var names = Ember.keys(object);
  var i, l, name;
  for (i = 0, l = names.length; i < l; i++ ) {
    name = names[i];
    if (object.hasOwnProperty(name) && object[name]) { return true; }
  }

  return false;
}
/*
This file encapsulates the various states that a record can transition
through during its lifecycle.
 
### State

Each record has a `currentState` property that explicitly tracks what
state a record is in at any given time. For instance, if a record is
newly created and has not yet been sent to the adapter to be saved,
it would be in the `root.loaded.created.uncommitted` state.  If a
record has had local modifications made to it that are in the
process of being saved, the record would be in the
`root.loaded.updated.inFlight` state. (These state paths will be
explained in more detail below.)

Events are sent by the record or its store to the record's
`currentState` property. How the state reacts to these events is
dependent on which state it is in. In some states, certain events
will be invalid and will cause an exception to be raised.

States are hierarchical and every state is a substate of the
`RootState`. For example, a record can be in the
`root.deleted.uncommitted` state, then transition into the
`root.deleted.inFlight` state. If a child state does not implement
an event handler, the state manager will attempt to invoke the event
on all parent states until the root state is reached. The state
hierarchy of a record is described in terms of a path string. You
can determine a record's current state by getting the state's
`stateName` property:

```javascript
record.get('currentState.stateName');
=> "root.created.uncommitted"
```

The hierarchy of valid states that ship with ember data looks like
this:

```text
root
deleted
saved
uncommitted
inFlight
empty
loaded
created
uncommitted
inFlight
saved
updated
uncommitted
inFlight
loading
```

The `DS.Model` states are themselves stateless. What we mean is
that, the hierarchical states that each of *those* points to is a
shared data structure. For performance reasons, instead of each
record getting its own copy of the hierarchy of states, each record
points to this global, immutable shared instance. How does a state
know which record it should be acting on? We pass the record
instance into the state's event handlers as the first argument.

The record passed as the first parameter is where you should stash
state about the record if needed; you should never store data on the state
object itself.

### Events and Flags

A state may implement zero or more events and flags.

#### Events

Events are named functions that are invoked when sent to a record. The
record will first look for a method with the given name on the
current state. If no method is found, it will search the current
state's parent, and then its grandparent, and so on until reaching
the top of the hierarchy. If the root is reached without an event
handler being found, an exception will be raised. This can be very
helpful when debugging new features.

Here's an example implementation of a state with a `myEvent` event handler:

```javascript
aState: DS.State.create({
myEvent: function(manager, param) {
console.log("Received myEvent with", param);
}
})
```

To trigger this event:

```javascript
record.send('myEvent', 'foo');
=> "Received myEvent with foo"
```

Note that an optional parameter can be sent to a record's `send()` method,
which will be passed as the second parameter to the event handler.

Events should transition to a different state if appropriate. This can be
done by calling the record's `transitionTo()` method with a path to the
desired state. The state manager will attempt to resolve the state path
relative to the current state. If no state is found at that path, it will
attempt to resolve it relative to the current state's parent, and then its
parent, and so on until the root is reached. For example, imagine a hierarchy
like this:

created
uncommitted <-- currentState
inFlight
updated
inFlight

If we are currently in the `uncommitted` state, calling
`transitionTo('inFlight')` would transition to the `created.inFlight` state,
while calling `transitionTo('updated.inFlight')` would transition to
the `updated.inFlight` state.

Remember that *only events* should ever cause a state transition. You should
never call `transitionTo()` from outside a state's event handler. If you are
tempted to do so, create a new event and send that to the state manager.

#### Flags

Flags are Boolean values that can be used to introspect a record's current
state in a more user-friendly way than examining its state path. For example,
instead of doing this:

```javascript
var statePath = record.get('stateManager.currentPath');
if (statePath === 'created.inFlight') {
doSomething();
}
```

You can say:

```javascript
if (record.get('isNew') && record.get('isSaving')) {
doSomething();
}
```

If your state does not set a value for a given flag, the value will
be inherited from its parent (or the first place in the state hierarchy
where it is defined).

The current set of flags are defined below. If you want to add a new flag,
in addition to the area below, you will also need to declare it in the
`DS.Model` class.


[isEmpty](DS.Model.html#property_isEmpty)
[isLoading](DS.Model.html#property_isLoading)
[isLoaded](DS.Model.html#property_isLoaded)
[isDirty](DS.Model.html#property_isDirty)
[isSaving](DS.Model.html#property_isSaving)
[isDeleted](DS.Model.html#property_isDeleted)
[isNew](DS.Model.html#property_isNew)
[isValid](DS.Model.html#property_isValid)

@namespace DS
@class RootState