Question

UPDATE

Okay, what luck…this is now the default behavior as of Ember 1.5. Yay!

Original question

Something that really seems intuitive to me but isn't the case in the Ember router. I have a bunch of resources, the vast bulk of which have an index route where I want the model to be the same as the resource route's model--that is, the object selected by convention using the dynamic segment. E.g.:

this.resource("chargeRule", { path: "/chargeRule/:chargeRule_id" }, function(){});

I'm going to be using nesting, so I can't do everything in my chargeRule template, because that template is going to have little but {{outlet}} (kinda like this guy). So my index route is going to be my read-only view in most cases and I'll have an edit sub-route to update a model where needed.

What bugs me is, the default model for an index route (and any other sub-route) is: NOTHING! Tada! Null I think, though it could be empty string or something. So, I now have to create a bunch of tiny Ember.Route subclasses that look exactly like this:

App.ChargeRuleIndexRoute = Ember.Route.extend({
    model: function() {
        return this.modelFor('chargeRule');
    }
});

Repeat ad-nauseum for each different model class/route. Really, then about double it because I want the same for /index and /edit routes, maybe more. Personally, I would have thought that the default model (since you can override it anyway) for any child route should have been the parent route's model instead of nothing, but I'd be interested in explanations as to why it's not.

But my question is, can anybody come up with a way for me to make the behavior I'm describing the default in my app? Something I can reopen? So I don't have a dozen or more boilerplate 5-line route objects?

Edit

I might should mention that I know my gripe might seem trivial, but the fact that I have to create so many route subclasses also implies that I should create individual files for each class…right? So that future developers can easily find where a given class is defined? I know that's not an absolute, but is a good practice, I think, and would require me to make as many tiny JS files as tiny classes…which is why I started thinking in terms of changing the default behavior. I'll take comments on that though.

Was it helpful?

Solution

UPDATE

See note at top of question, this is no longer necessary...

Based on @kingpin2k 's answer, I came up with this more generalized possibility:

App.ParentModelRoute = Ember.Route.extend({
    model: function() {
        return this.modelFor(this.get('routeName').replace(/\..*$/, ''));
    }
});

App.ChargeRuleIndexRoute = App.ParentModelRoute.extend();
App.ChargeRuleEditRoute = App.ParentModelRoute.extend();
App.OtherIndexRoute = App.ParentModelRoute.extend();
.
.
.

Which certainly cuts down on the amount of code…but still requires me to explicitly declare a route class for each sub-route. It also may be a bit hacky (the routeName property isn't listed in the API docs?), though it's simple enough it should work pretty widely.

OTHER TIPS

The reason is due to the fact that a route doesn't necessarily have to contain a model. Think of the case of a Albums/New route. It wouldn't actually have the albums resource as its model. For this reason there is no set rule for what the model should be for a model.

That being said, if you feel like lazily building up some sort of default route for your route and extending this, that's entirely possible and can be accomplished a few different ways.

App.DefaultChargeRuleRoute = Ember.Route.extend({
    model: function() {
        return this.modelFor('chargeRule');
    }
});

App.ChargeRuleIndexRoute = App.DefaultChargeRuleRoute.extend();

App.ChargeRuleEditRoute = App.DefaultChargeRuleRoute.extend();

or if you wanted to make some generic model fetching route

App.ModelFetcherRoute = Ember.Mixin.create({
  model: function(){
    return this.modelFor(this.get('modelToFetch'));
  }
});


App.ChargeRuleIndexRoute = Ember.Route.extend(App.ModelFetcherRoute, {
  modelToFetch: 'chargeRule'
});

And this could follow the same pattern as the first example if you want to make it even smaller

App.DefaultChargeRuleRoute = Ember.Route.extend(App.ModelFetcherRoute, {
  modelToFetch: 'chargeRule'
});

App.ChargeRuleIndexRoute = App.DefaultChargeRuleRoute.extend();

App.ChargeRuleEditRoute = App.DefaultChargeRuleRoute.extend();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top