home
  • Blog
1.10
  • Getting Started
  • Getting Ember
  • Concepts
  • The Object Model
  • Application
  • Templates
  • Routing
  • Components
  • Controllers
  • Models
  • Views
  • Enumerables
  • Testing
  • Configuring Ember.js
  • Cookbook
  • Understanding Ember.js
  • Contributing to Ember.js
Old Guides - You are viewing the guides for Ember v1.10.0.
Go to v5.0.0

Edit pencil

Problem

The default behavior of Ember's link-to helper and Ember.Route's model hook make it easy to identify and load records by id. However, you may want to use a human-readable keyword or slug to identify a record in a url in place of an id.

Solution

Ember makes it easy to override the Route's default model hook. You can define a custom model function to look up records by a slug property instead of by the id.

Changing the link-to to use a slug instead of an id is easy and only requires creating a custom serialize function on the route.

Discussion

Identifying records by slugs is a two step problem. Given a Router mapping that looks like this:

App.Router.map(function() {
  this.route('post', { path: '/post/:post_slug' });
});

First the Router needs to know how to look up the record by the slug using the :post_slug param. Then link-to needs to generate an anchor tag with the record's slug property in place of the :post_slug.

Querying Records by Slug

By default, Ember Data does not provide a way to look up only 1 record by a property (other then the id property). Luckily, it is easy to extend Ember Data's store object to provide this functionality. The code below adds a findOne method to the store.

App.ApplicationStore = DS.Store.extend({
  findOne: function() {
    return this.find.apply(this, arguments).then(function(results) {
      return results.objectAt(0);
    });
  }
});

Using findOne we can easily fetch a record by its slug property in the Route's model hook.

App.PostRoute = Ember.Route.extend({
  model: function(params) {
    return this.store.findOne('post', {slug: params.post_slug});
  }
});

Linking To the Slug

The next step is to include a record's slug in the anchor tag generated by ember's link-to helper. The normal way to create a link-to would look something like this:

{{#link-to 'post' model}}{{model.slug}}{{/link-to}}

Unfortunately it will generate an anchor tag that includes the Post's id in the dynamic segment.

<a href="/post/1">hamster</a>

You can work around this behavior by defining a custom serialize method on the route.

App.PostRoute = Ember.Route.extend({
  serialize: function(model) {
    return {
      post_slug: model.get('slug')
    };
  }
});

Now using we can use the same link-to code as above and the records's slug property will be correctly serialize the :post_slug param in the anchor tag's href.

<a href="/post/hamster">hamster</a>

Example

Cookbook: Using slugs in links

On this page

  • Problem
  • Solution
  • Discussion
  • Querying Records by Slug
  • Linking To the Slug
  • Example
Team Sponsors Security Legal Branding Community Guidelines
Twitter GitHub Discord Mastodon

If you want help you can contact us by email, open an issue, or get realtime help by joining the Ember Discord.

© Copyright 2023 - Tilde Inc.
Ember.js is free, open source and always will be.


Ember is generously supported by
blue