## 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][1] to identify
a record in a url in place of an id.

## Solution

Ember makes it easy to override the Route's default
[model](http://emberjs.com/api/classes/Ember.Route.html#method_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](http://emberjs.com/api/classes/Ember.Route.html#method_serialize)
function on the route.

## Discussion

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

```js
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.

```js
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.

```js
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:

```handlebars
{{#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.

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

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

```js
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.


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

## Example
<a class="jsbin-embed" href="http://emberjs.jsbin.com/sihubaza/1/edit?output">
Cookbook: Using slugs in links
</a>


  [1]: https://en.wikipedia.org/wiki/Slug_(web_publishing)#Slug
