Q:

Ember routes not loaded in order

I'm having an issue where the beforeModel (or afterModel) on my route isn't called after the application controller has been setup.  This is an issue because I need some data from the application controller. 
In another route this works as I'd expect (that the application controller is loaded prior to the route).  The only difference is the one that works is an Ember. ArrayController and the one that doesn't is a standard Ember. Controller.  I'm using beforeModel even though there isn't a model simply because I'm trying to transition away from it if a condition isn't meet. 
If I change my non-working controller to an Ember. ArrayController and put in a pointless model call in the router then it still doesn't work. 
The only other difference I can think of is that the one that isn't working is a nested controller defined by just a route and the working one isn't nested and is defined by resource. 
Router.map(function() {

  this.resource("wizard", function() {
    this.resource("wizard/schools", {path: "/schools"}, function() {
      this.route("new"); // This one doesn't work
    });
  });

  ...

  this.resource("schools", { path: "/schools" }); // This one does work
});

Any idea how I can ensure the application route/controller is loaded prior to my route? 
I'm trying to do something along the lines of:
beforeModel: function() {
  var customerAccountPromise = this.controllerFor('application').get('customerAccount');
  var self = this;
  return customerAccountPromise.then(function(customerAccount) {
    return self.get('store').find('school').then(function(schools) {
      if (customerAccount.get('schoolLimit') <= schools.get('length')){
        self.transitionTo('school', schools.get('firstObject'));
      }
    });
  });
},

I'm currently running:
DEBUG: Ember      : 1.8.1
DEBUG: Ember Data : 1.0.0-beta.12
DEBUG: Handlebars : 1.3.0
DEBUG: jQuery     : 1.11.1

Update: here is the code for the working route:
import Ember from 'ember';
import AuthenticatedRoute from "./authenticated";

var SchoolsRoute = AuthenticatedRoute.extend({
  model: function() {
    return this.get('store').find('school');
  },
  afterModel: function(schools) {
    Ember. Logger.log("SchoolsRoute - afterModel");
    var customerAccountPromise = this.controllerFor('application').get('customerAccount');
    var self = this;
    return customerAccountPromise.then(function(customerAccount) {
      if (customerAccount.get('schoolLimit') === 1){
        self.transitionTo('school', schools.get('firstObject'));
      }
    });
  },
});

export default SchoolsRoute;
The application controller is just aliasing the session controller. 
import Ember from 'ember';

var ApplicationController = Ember.Controller.extend({
  needs: ['session'],

  currentUser: Ember.computed.alias('controllers.session.currentUser'),
  customerAccount: Ember.computed.alias('currentUser.customerAccount'),

  ...
});

export default ApplicationController;

The router for the application is pretty simple:
import Ember from 'ember';

var ApplicationRoute = Ember.Route.extend({
  setupController: function(controller, model) {
    Ember. Logger.log("application setupController");
    return this._super(controller, model);
  },
  ...
});

export default ApplicationRoute;

The important part in AuthenticatedRoute is the beforeModel:
beforeModel: function(transition) {
  Ember. Logger.log("AuthenticatedRoute - beforeModel");
  if (Ember.isEmpty(this.controllerFor('session').get('token'))) {
    // set notification
    return this.redirectToSignIn(transition);
  }
},

There is no other "setting up" of the SessionController.  It is simply called via the controllerFor.  And on init it calls a loadUser method which immediately logs the message "SessionController - loadUser" and then does a store.find call and when that returns it logs a message about setting the user. 
And the logs show that the application gets setup first:
DEBUG: -------------------------------
DEBUG: Ember      : 1.8.1
DEBUG: Ember Data : 1.0.0-beta.12
DEBUG: Handlebars : 1.3.0
DEBUG: jQuery     : 1.11.1
DEBUG: -------------------------------
AuthenticatedRoute - beforeModel
SessionController - loadUser
generated -> route:loading Object {fullName: "route:loading"}
application setupController
Rendering application with default view <school-app@view:toplevel::ember365> Object {fullName: "view:application"}
generated -> controller:loading Object {fullName: "controller:loading"}
Rendering loading with default view <school-app@view:default::ember386> Object {fullName: "view:loading"}
XHR finished loading: GET "http://0.0.0.0:4200/api/users?email=ryan%40ryanjm.com". 
SessionController - set user
Ember Inspector Active
XHR finished loading: GET "http://0.0.0.0:4200/api/school". 
SchoolsRoute - afterModel

Here is the session controller:
import Ember from 'ember';

var SessionController = Ember.Controller.extend({
  // called by updateHeaders
  loadUser: function() {
    Ember. Logger.log("SessionController - loadUser");
    if (this.get('isSignedIn') && ! this.get('currentUser')){
      var self = this;
      this.store.find('user', { email: this.get('email') }).then(function(users) {
        Ember. Logger.log("SessionController - set user");
        self.set('currentUser', users.get('firstObject'));
      });
    }
  },

  // if email/token change, update the headers
  updateHeaders: function() {
    if (this.get('isSignedIn')){
      Ember.$.ajaxSetup({
        headers: {
          'X-User-Email': this.get('email'),
          'X-User-Token': this.get('token')
        }
      });
      this.loadUser();
    }
  }.observes('email', 'token').on('init'),

  hasEmail: Ember.computed.notEmpty('email'),
  hasToken: Ember.computed.notEmpty('token'),
  isSignedIn: Ember.computed.and('hasEmail', 'hasToken'),

});

export default SessionController;

Based on Kingpin2k's suggestion I looked at the case of it being a race condition and that was the issue. 
Therefore I changed my SessionController to a normal object and then injected it into the application route so that I could return the loadUser function as a promise in the beforeModel. 

A:

All model hooks (for the url) are called before any controllers are instantiated or hooked up.   It's likely it appeared that your application controller was set up for one of your routes because you'd already visited a parent route which had already instantiated and hooked up the model on the application controller.   Try refreshing the page on the route that you think is working, and it's likely that application controller won't have been hooked up (or you're doing it during setupController which the application controller would have been then hooked up as well).   
That being said, you likely need the data from the underlying model that's on the application controller.   You can use modelFor to get the model from the application controller and perform your logic.   Additionally, since you don't need any data from the customer's account to get the schools, you can make those calls concurrently instead of serially.   
beforeModel: function() {
  var customerAccountPromise = this.modelFor('application').get('customerAccount'),
      self = this;
  return Em.RSVP.hash({
       customerAccount: customerAccountPromise,
       schools: this.store.find('school')
  }).then(function(hash) {
      if (hash.customerAccount.get('schoolLimit') <= hash.schools.get('length')){
        self.transitionTo('school', hash.schools.get('firstObject'));
      }
  });
  // also you don't have anything to catch the exception if something goes wrong here! 
},

P.S. Each time you hit this route you'll go and fetch all of the schools from the server.   You might consider fetching all of the schools once, and then just asking for all of the schools from the store instead of making a call for them each time.   But that's just a suggestion that might not make sense with your business logic. 
Promisify your user loading
var SessionController = Ember.Controller.extend({
  // called by updateHeaders
  loadUser: function() {
    Ember. Logger.log("SessionController - loadUser");
    if (this.get('isSignedIn') && ! this.get('currentUser')){
      var self = this;
      var loadingPromise = this.store.find('user', { email: this.get('email') }).then(function(users) {
        Ember. Logger.log("SessionController - set user");
        self.set('currentUser', users.get('firstObject'));
      });
      this.set('loadingPromise', loadingPromise);
    }
  },

  // if email/token change, update the headers
  updateHeaders: function() {
    if (this.get('isSignedIn')){
      Ember.$.ajaxSetup({
        headers: {
          'X-User-Email': this.get('email'),
          'X-User-Token': this.get('token')
        }
      });
      this.loadUser();
    }
  }.observes('email', 'token').on('init'),

  hasEmail: Ember.computed.notEmpty('email'),
  hasToken: Ember.computed.notEmpty('token'),
  isSignedIn: Ember.computed.and('hasEmail', 'hasToken'),
  loadingPromise: Ember.RSVP.reject()

});

Authenticated route
beforeModel: function(transition) {
  Ember. Logger.log("AuthenticatedRoute - beforeModel");
  var sessionController = this.controllerFor('session');
  if (sessionController.get('hasToken')) {
    // set notification
    return this.redirectToSignIn(transition);
  } else {
    return sessionController.get('loadingPromise');
  }
},

Bleh, I just realized while writing this, that you're overriding the beforeModel hook which was implemented in AuthenticatedRoute, so when you hit that route it doesn't fire the beforeModel hook.   Try this before the other changes and see if it fixes your expected result. 
beforeModel: function(transition) {
  this._super(transition)
  var customerAccountPromise = this.modelFor('application').get('customerAccount'),
      self = this;
  return Em.RSVP.hash({
       customerAccount: customerAccountPromise,
       schools: this.store.find('school')
  }).then(function(hash) {
      if (hash.customerAccount.get('schoolLimit') <= hash.schools.get('length')){
        self.transitionTo('school', hash.schools.get('firstObject'));
      }
  });
  // also you don't have anything to catch the exception if something goes wrong here! 
},

