Chris Hayes
Chris Hayes

Reputation: 127

Ember.js Routes - Best Way to Filter By a Different Model

I'm trying to create a route structure where I can view a list of all members (/members) or filter them by group (members/group-slug-to-filter-by). I have a Member model as well as a Group model, as well as the following routes:

this.resource('members', function() {
    this.route('/');
    this.route('group', { path: ':group_slug' });
});

My MembersGroup route looks like this:

var MembersGroupRoute = Ember.Route.extend({
    model: function(params) {
        // Just have this here temporarily for testing purposes,
        // but ultimately this is where I would filter by group slug
        return this.store.find('member').then(function(models) {
            return models.slice(0, 2);
        });
    },

    serialize: function(model) {
        return { 'group_slug': model.get('slug') };
    }
});

Essentially I have a bulleted list displaying each of the groups, and a link-to that I want to pass a group model into:

<ul class="nav nav-pills nav-stacked">
    {{#each group in groups}}
        <li>{{#link-to 'members.group' group class="list-group-item"}}{{group.name}} <span class="badge">{{group.memberCount}}</span>{{/link-to}}</li>
    {{/each}}
</ul>

When doing it this way, I'm providing a model to the link-to helper, and it therefore transitions to the members.group route without executing the model hook; this is a problem because I can't take the passed-in group model, re-execute the model hook, and filter by the group's slug.

If I pass in the group slug (as a string, rather than the group model) the model hook is executed and the list is filtered:

<li>{{#link-to 'members.group' group.slug class="list-group-item"}}{{group.name}} <span class="badge">{{group.memberCount}}</span>{{/link-to}}</li>

What is the best way to go about this functionality? Should I restructure my routes, just continue passing in the group slug, or is there a way to get this to work while passing in the group model?

I'm pretty sure I could just use actions on the links to filter by the group model, but I want to have the URL reflect the group that is being filtered (ie. members/group-slug).

Thanks!

Upvotes: 0

Views: 264

Answers (1)

joegoldbeck
joegoldbeck

Reputation: 546

If you'll generally be passing in the slug, rather than the filtered group (presumably because you don't have access to the filtered group from where the link-to), consider making the slug the model of the route. At the controller level, you'll want the model to actually be the filtered group, and you can use the setupController hook to do this. In this case, you wouldn't need to define model or serialize hooks, and your route could look something like the following:

var MembersGroupRoute = Ember.Route.extend({
    setupController: function(controller, model) {
        slug = model;
        controller.set 'model', this.store.find('member', groupSlug: slug).then(function(models) {
            return models.slice(0, 2);
        });
    }
});

Then you would call your routes the second way you present above:

<li>{{#link-to 'members.group' group.slug class="list-group-item"}}{{group.name}}

You could also do a similar thing and have the unfiltered group as the model in the model hook, and as what gets passed in via link-to's, and then use the setupController hook to filter members by this group before setting the model of the controller.

So that would be:

var MembersGroupRoute = Ember.Route.extend({
    model: function(params) {
        return this.store.find('group', slug: params.group_slug)
    },
    serialize: function(model) {
        return { 'group_slug': model.get('slug') };
    },
    setupController: function(controller, model) {
        group = model;
        controller.set 'model', this.store.find('member', group: group)
    }
});

And you call routes in the first way you present above:

 <li>{{#link-to 'members.group' group class="list-group-item"}}{{group.name}} <span class="badge">{{group.memberCount}}</span>{{/link-to}}</li>

Upvotes: 1

Related Questions